Ruby on Rails3でファイルを直接アップロード
今回はファイルのアップロードですが、データベースにではなく直接ファイルを流します。
そのため管理者であるということを条件として作成していきます。
ですのでadministratorは管理者であるという意味です。
そしてadministrator内にfileを作成し、その中にnew.html.erbとdone.html.erbを作成します。
まずはroutes.rbの作成です。管理者になっている(ログインしている)という意味のcollection
にget内にdoneとnewを追加します。
今回使うファイルはdone.html.erbとnew.html.erbだけなのでこれだけです。
new自体はお決まりのindex,new,show,edit,createの中に入っているので指定する必要はないのですが、indexがないためnewに直接飛ばすという意味で指定しました。
resources :files do get :done, :new, :on => :collection end
次にコントローラーです。見た感じcreateしか指定していません。doneとnewは空で結構です。
●まずupload = params[:upload_image]でパラメーターを指定します。
●次にunless params[:upload_image].blank?でパラメーターが空でないか調べます
●そして@filename = save_image_file(upload)と@filename = save_file(upload)は@filenameに
情報を入れています。save_image_fileもsave_fileもモデルなどで作ります。(今回はpravate指定のコントローラー内で作成)
●render :action => :doneでdoneに飛ばしています。
●flash[:warning] = 'ファイル名が空です'はunless以外の時にメッセージを出します。
●redirect_to params[:from] || :administrator_filesはメッセージ出力後redirect_toでnewに飛ばしています
class Administrator::FilesController < Administrator::Base def new end def create unless params[:upload_image].blank? upload = params[:upload_image] @filename = save_image_file(upload) render :action => :done return end unless params[:upload_file].blank? upload = params[:upload_file] @filename = save_file(upload) render :action => :done return end flash[:warning] = 'ファイル名が空です' redirect_to params[:from] || :administrator_files end def done end
次にsave_image_fileとsave_fileを作成します。プログラムが多くなる場合モデルに書いた方がいいのですが今回はpravate指定をしてコントローラーで作成しました。
●original_filenameは送られてきたファイル情報からファイル名だけを取り出す処理です
●unless upload.original_filename.blank?はファイルが空ではないという条件
●送られるファイル情報をfilenameとする
●送られて来ているファイルの送信先をfiledirとする
●送られたファイルをjoinでファイル・パスの区切り文字を気にしないでRubyがうまくつなげる処理
●f = File.open(filepath, "wb")はファイル操作を行うという意味で"wb"はw=writeでb=バイナリを意味しその書き込み先がfilepathである
●f.write(upload.read)は中身を読みそれをファイルに書き込む作業
●save_fileもsave_image_fileも行き先が違うだけで内容は同じです
private def save_image_file(upload) unless upload.original_filename.blank? filename = upload.original_filename filedir = "public/images/abcd_self" filepath = File.join(filedir,filename) f = File.open(filepath, "wb") f.write(upload.read) f.close return filename end end def save_file(upload) unless upload.original_filename.blank? filename = upload.original_filename filedir = "app/views/abcd/abcd_self" filepath = File.join(filedir,filename) f = File.open(filepath, "wb") f.write(upload.read) f.close return filename end end end
次にようやくnewの作成です。
●<% if flash[:warning] -%><%= flash[:warning] %><% end -%>で空の時のメッセージを出します。
●<%= form_tag [ :administrator, :files ], :multipart => true do %>〜<% end %>でフォームの作成です。administrator内のfilesであるということです
●<%= file_field_tag 'upload_image' %>はファイルを参照するフィールドです
●<%= submit_tag "アップロード" %>でアップロードボタンの作成です
これでイメージ用とファイル用二つ作りました。空の場合上にメッセージも出力されます。
<h2>ファイルアップロード</h2> <% if flash[:warning] -%> <p id="warning"><%= flash[:warning] %></p> <% end -%> <%= form_tag [ :administrator, :files ], :multipart => true do %> 画像ファイルを選択して下さい:(*.jpg, *.gif, ...)<br/> <%= file_field_tag 'upload_image' %><br/> <%= submit_tag "アップロード" %><br/> <% end %> <br/> <%= form_tag [ :administrator, :files ], :multipart => true do %> テンプレートファイルを選択して下さい:(*.html.erb)<br/> <%= file_field_tag 'upload_file' %><br/> <%= submit_tag "アップロード" %><br/> <% end %> <br/>
最後にファイルを受け取るdoneの作成です。
●ファイル名:<%= @filename %>はコントローラーで指定した@filename = save_image_file(upload)と@filename = save_file(upload)なので、ファイル名が出力されます。
●<%= link_to 'アップロードを続ける', :administrator_files %>でnewに戻って何度もアップロードできます。
<h1>アップロードしました</h1> ファイル名:<%= @filename %> <br/> <p><%= link_to 'アップロードを続ける', :administrator_files %></p>
以上でアップロードができました。