2007-05-30
file_column + respond_to_parent を使って画面遷移なしでファイルアップロードする
ここではプロフィール画像を例にとってみます。
まず、両プラグインをインストール。
- file_column
ruby script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk
インストールしたら一通り公式サイトに沿って設定します。
http://www.kanthak.net/opensource/file_column/
ここでは、モデル profile.rb に対して image というカラムを追加しています。
- responds_to_parent
ruby script/plugin install http://sean.treadway.info/svn/plugins/responds_to_parent/
- View
<% form_tag({:action => 'image_upload', :id => @profile},
{:name => 'ProfileImageForm', :multipart => true, :method => 'post', :target => 'frame'}) do -%>
<span id='profile_image_file'><%= render :partial => 'profile_image_file' -%></span>
<% end -%>
<iframe id="frame" name="frame" scrolling="auto" frameborder="0" style="width: 100%; height: 100%;
position: absolute; top: 0pt; left: -10000px;" ></iframe>
iframe の属性は gmail をマネしてます。
次に _profile_image_file.rhtml を作ります。
<% if @profile.image.nil? -%> <%= image_tag("/image/default.gif") -%> <% else -%> <%= image_tag(url_for_image_column(@profile, "image")) -%> <%= submit_tag _("Delete"), "name"=>"btn_delete_image" %> <% end -%> <br/> <%= file_column_field "profile", "image", {:onchange => "document.ProfileImageForm.submit();"} %>
- Controller
def image_upload @profile = Profile.find(params[:id]) if params[:btn_delete_image] @profile.image = nil @profile.save else @profile.update_attributes(params[:profile]) end responds_to_parent do html = render_to_string :partial => 'profile_image_file' render :update do |page| page.replace_html 'profile_image_file', html end end end
- 画像削除は公式な方法があるのかな?後で調べる。
- 画像表示のヘルパー作ると表示がすっきりしそう。
- アップロード中というのがわかる画像を表示するとさらに良さそう。
- 2007/06/08
- 画像削除は自前で行わなくても、nil を代入した上で save を呼ぶとファイルを消してくれるようなので、そのように修正。
コメントありがとうございます。
ソースを確認してみました。
image = nil した上で save で消してくれるようですね。
記事も修正してみます。