Ruby on Rails: ファイルアップロード機能を作る Rails 2.1.0版
Railsでファイルをアップロードするところを参考にさせていただいた。
"Ruby on Rails: ファイルアップロード機能を作る" http://www.negisio.net/?p=30
Railsなどの環境が変わってそのままでは動かなかったので、修正して動かせることができました。
Rails 2.1.0
SQLite 3使用
will_paginate使用
$ rails uploader
paginateは、rails 2.0より標準で使われなくなった。そのためwill_paginateを使う。
今日現在(2008/8/11)は、will_paginateはgemでインストールする。
$ gem install will_paginate
そしてRailsのenvironment.rbの最後に以下を追加する。
require 'will_paginate'
Rails pluginはサポートしなくなったようだ。
そのほか
$ cat db/migrate/2008011xxxxx_create_attachments.rb class CreateAttachments < ActiveRecord::Migration def self.up create_table :attachments do |t| t.column(:content_type, :string) t.column(:filename, :string) t.column(:size, :integer) t.column(:data, :binary) end end def self.down drop_table :attachments end end
コントローラー
$ cat app/controllers/attachment_controller.rb class AttachmentController < ApplicationController # 新規アップロード画面を作る用。 def new end # アップロード処理 def create @uploaded = params[:upload] Attachment.create( :content_type => @uploaded['file'].content_type, :filename => @uploaded['file'].original_filename, :size => @uploaded['file'].size, :data => @uploaded['file'].read) redirect_to(:action => :list) end # ファイル一覧表示 def list @attachments = Attachment.paginate(:page => params[:page], :per_page => 10, :order => "id desc") end # ファイルダウンロード用。 # 注)日本語ファイル名は文字化けする。 # 右クリックで「対象をファイルに保存」するとファイル名がちゃんと出ない。 def view_file attachment = Attachment.find(params[:id]) send_data(attachment.data, {:filename => attachment.filename, :type => attachment.content_type}) end # ファイル削除 def destroy @attachment = Attachment.find(params[:id]) @attachment.destroy redirect_to(:action => :list) end end
ビュー
$ cat app/views/attachment/list.rhtml <h1>attachments list</h1> <table> <tr> <th>id</th> <th>filename</th> <th>content_type</th> <th>action</th> </tr> <% @attachments.each do |attachment| %> <tr> <td><%= h(attachment.id) %></td> <td><%= h(attachment.filename) %></td> <td><%= h(attachment.content_type) %></td> <td><%= link_to('(download)', {:action => 'view_file', :id => attachment.id}) %> <%= link_to('(destroy)', {:action => 'destroy', :id => attachment.id}) %></td> </tr> <% end %> </table> <%= will_paginate @attachments, :prev_label => 'prev', :next_label => 'next' %> <br /><br /> <%= link_to('new', {:action => 'new'}) %>
$ cat app/views/attachment/new.rhtml <h1>add attachment</h1> <% form_tag({:action => 'create'}, :multipart => true) do %> <%= file_field( :upload, 'file') %> <%= submit_tag('upload') %> <% end %>
ちょっと考えればわかることなんだけれど、will_paginateの使い方と、rails 2.1の使い方をよく間違えるので記録しておく。