WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

ファイルアップロードフォームの params を擬似的に生成する

今週もまたもや記事を書かずに終わってしまいそうなので、 Rails 関係の小技をご紹介。 Rails で attachment_fu などを使ってモデルレベルでファイルアップロードを実装すると、基本的にフォーム経由でしかファイルアップロードができなくなります(フィールドに直接アクセスすれば別ですが)。これではユニットテストや Rake タスクでのデータの初期化などに不便ですよね。

そんなわけで、ファイルアップロードフォームが生成する params を擬似的に再現する関数を作ってみました。これを使えば、ローカルファイルやプログラム的に生成したデータを直接モデルに引き渡せます。けっこう便利だと思いますので、ぜひ使ってみてください。

ソースファイル

ソースはいつもどおりcodeなにがしに投稿してあります。

ご自分のソースに適当にコピペして使ってください(^^ゞ

使い方

基本的に、関数にアップロードしたいファイルやデータを渡すと params のデータを返しますので、それをモデルのコンストラクタや attributes に渡すだけです。例えば以下のようなモデルがある場合。

class Attachment < ActiveRecord::Base
  has_attachment :storage => :file_system, :path_prefix => 'attachments'
  validates_as_attachment
end

以下のようにしてローカルファイルをアップロード(?)できます。第 1 引数はアップロードするローカルファイルのパス名、第 2 引数は mime タイプです。最後の form.close は必須ではありませんが、やっておいたほうが無難です。

form = pseudo_upload_form('/path/to/file.png', 'image/png')
Attachment.new({ :uploaded_data => form }).save!
form.close

内部的に生成したデータをアップロードするときは、第 3 引数に指定してください。第 1 引数のファイル名は、(擬似的な)アップロードファイル名として使われます。

form = pseudo_upload_form('/sample.txt',
                          'text/plain',
                          'ファイルの中身になる文字列')
Attachment.new({ :uploaded_data => form }).save!
form.close

以上、使い方はこれだけです。このあたりは基本的に cgi.rb の仕様そのままなので、 Rails 以外でも使えるはずです。ぜひお役立てください。

ということで、短いですが、本日はこれにて(^^)/


追記

はてぶにて何人かの方がご指摘くださっていますが、 fixture_file_upload というのがあるみたいですね。まあ、ありそうだとは思ったのですが、作る前に適当にググった範囲では見つけることができませんでした。それがわかっただけでも記事にした甲斐があったというものでしょう(^^ヾ はてぶでご指摘くださった方々に感謝です。

それはそれとして、 fixture_file_upload にはない私の関数の特徴は

  • スクリプト内で生成したデータもアップロードできる
  • ActionController がなくても使える(rake タスク内で使うのに便利?)

というあたりでしょうか。超レアケースですが(笑)、こんな状況に遭遇したら使ってください。

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles