3. ファイルアップロード2006.08.09 株式会社四次元データ 岡本和也
Ruby on Rails 3章 ファイルアップロード
本章ではこれまでの章において構築してきた Web アプリケーションにファイルアップロード機能を追加します。 これまで日記形式の Web アプリケーションを構築してきましたが、画像が無いために少し寂しい感じがするのでは ないでしょうか。そこで、画像ファイルのアップロードと表示を行いたいと思います。一般的に画像情報はテキスト情報に比べて 大きくなりますので、データベースに画像ファイルを格納するのはお勧めできません。そこで、データベースには 画像ファイルの位置情報を保持させることにします。では、MySQL にアクセスして画像ファイルの位置情報を格納する列を追加 しましょう。下記のコードをコマンドラインで実行してください。 $ mysql -u root -p
Enter password: ****
mysql> use diary
Database Changed
mysql> alter table items add
-> picture_url varchar( 100 )
-> ;
これでテーブルに画像ファイルの位置情報を格納する列を1つ追加することができました。次に、\app\views\items にある new.rhtml ファイルを書き換えます。このファイルには新しい記事を追加する際のインタフェースが記述されています。 1:<form action="create" method="post" enctype="multipart/form-data"> 2: <p> 3: <b>Title:</b><br /> 4: <%= text_field "item", "title", "maxlength" => 20 %> 5: </p> 6: <p> 7: <b>Text:</b><br /> 8: <%= text_area "item", "text", "cols" => 40, "rows" => 8 %> 9: </p> 10: <p> 11: <b>Picture:</b><br /> 12: <%= file_field "file", "picture", "size" => 60 %> 13: </p> 14: <p><input type="submit" value="投稿" /></p> 15:</form> 16:<%= link_to 'Back', :action => 'list' %> 1行目では multipart/form-data 形式で post メソッドによりデータを送信すると指定しています。
これは複数の form 入力データを複数データとして送るために指定しています。 次に、コントローラファイルを書き換えましょう。\app\controllers\items_controller.rb の create メソッドを書き換えます。 1:def create 2: @item = Item.new(params[:item]) 3: @item.postingdate = Time.now 4: @filename = params[:file]['picture'].original_filename 5: if @filename != "" then 6: @item.picture_url = "http://localhost:3000/images/" + @filename 7: Item.save(params[:file]['picture']) 8: end 9: if @item.save 10: flash[:notice] = 'Item was successfully created.' 11: redirect_to :action => 'list' 12: else 13: render :action => 'new' 14: end 15:end 変更点は4行目から8行目を追加したことです。まず、4行目で file オブジェクトの picture 要素に入っているファイル情報に
アクセスして original_filename 操作でファイル名を調べ、@filename 変数に格納しています。5行目はファイル名が
あればという条件になっていますが、日記の記事を投稿する際にファイルが指定されていれば6, 7行目を行う
という意味になります。6行目では指定ファイルがアップロードされる場所をテーブルの picture_url 列に入れるよう
指定しています。(実際の格納命令は9行目の @item.save です。)アップロードファイルは内部的には \public\images フォルダに
アップロードされます(格納フォルダは後で指定します)が、外部的には /images/ 以下にアップロードされますので、
6行目のように指定しておきます。7行目で Item モデルに対してファイルをアップロードするように指示しています。 1:class Item < ActiveRecord::Base
2: def self.save(file)
3: File.open("public/images/#{file.original_filename}", "wb"){ |f| f.write(file.read) }
4: end
5:end
2行目から4行目を追加しました。簡単に説明しますと、2行目において引数として file という情報の集合を受け取っています。 さらに、3行目で \public\images\[アップロードファイル名] の場所を書き込み可能なバイナリ形式でアクセス可能にし、 ファイル情報を書き込んでいます。 以上の操作によりファイルのアップロードが完了しました。最後に画像ファイルを見れるようにビューファイルを書き換えます。 \app\views\items\list.rhtml ファイルを以下のように書き換えてください。 1:<h1>ブログ</h1>
2:<%= link_to 'New item', :action => 'new' %>
3:<hr />
4:<% @items.each do |@item| %>
5: <h3><%= @item.title %></h3>
6: <%= @item.text %>
7: <br />
8: <% if @item.picture_url != nil then %>
9: <p><img src="<%= @item.picture_url %>" alt="picture"></p>
10: <br />
11: <% end %>
12: <%= @item.postingdate %>
13: <br />
14: <%= link_to 'Show', :action => 'show', :id => @item.id %>
15: <%= link_to 'Edit', :action => 'edit', :id => @item.id %>
16: <%= link_to 'Destroy', { :action => 'destroy', :id => @item.id }, :confirm => 'この記事を消去していいですか?', :post => true %>
17: <br />
18: <hr />
19:<% end %>
8行目から11行目を追加しました。8行目の if 文により items テーブルの picture_url 列に値が無い場合は、 画像ファイルの表示を行いません。値がある場合は、9行目でその値を用いてアップロードファイルにアクセスして、 画像ファイルとして表示させます。 画像ファイルを表示させることができたでしょうか。次章ではメールを使って記事の投稿を行えるようにします。 |
![]()
![]()
|