ファイルアップロードフォームの params を擬似的に生成する
今週もまたもや記事を書かずに終わってしまいそうなので、 Rails 関係の小技をご紹介。 Rails で attachment_fu などを使ってモデルレベルでファイルアップロードを実装すると、基本的にフォーム経由でしかファイルアップロードができなくなります(フィールドに直接アクセスすれば別ですが)。これではユニットテストや Rake タスクでのデータの初期化などに不便ですよね。
そんなわけで、ファイルアップロードフォームが生成する params を擬似的に再現する関数を作ってみました。これを使えば、ローカルファイルやプログラム的に生成したデータを直接モデルに引き渡せます。けっこう便利だと思いますので、ぜひ使ってみてください。
ソースファイル
使い方
基本的に、関数にアップロードしたいファイルやデータを渡すと 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 タスク内で使うのに便利?)
というあたりでしょうか。超レアケースですが(笑)、こんな状況に遭遇したら使ってください。
詳しくはこちらの記事をどうぞ!
この記事にコメントする