Rails2.0 でのファイルアップロード方法

移転しました。

以下本、P466の応用。本ではDBに画像データを保存してしまっているが、以下例ではDBには画像パスのみを指定し、publicフォルダ配下に画像データを保存する。

DBは事前に作成してあるものとする。

DB作成する

1. db/migrate/001_create_pictures.rb 作成

class CreatePictures < ActiveRecord::Migration
  def self.up
    create_table :pictures do |t|
      t.column :comment, :string
      t.column :name, :string
      t.column :content_type, :string
      t.column :file_url, :string
    end
  end
  
  def self.down
    drop_table :pictures
  end
end

2. db:migrate 実行

コントローラー作成

class RobocupMainController < ApplicationController

  protect_from_forgery :secret => 'shohu'

  def top
    @picture = Picture.new
  end

  # ファイルアップロード
  def create
    @picture = Picture.new(params[:picture])
    if @picture.save
      redirect_to(:action => 'show', :id=>@picture.id)
    else
      render(:action => :top)
    end
  end
  
  def show
    @picture = Picture.find(params[:id])
  end
end

モデル作成

class Picture < ActiveRecord::Base
  def uploaded_picture=(picture_field)
    self.name = base_part_of(picture_field.original_filename)
    self.content_type = picture_field.content_type.chomp
    self.file_url = "/images/#{self.name}"
    File.open("public" + self.file_url, "wb"){ |f| f.write(picture_field.read) }
  end
  
  def base_part_of(file_name)
    File.basename(file_name).gsub(/[^\w._-]/, '')
  end
end

HTML作成

・app/view/hoge/top.rhtml

<h1>Main#top</h1>
<% form_for(:picture,
			:url=>{:action => 'create'},
			:html=> {:multipart=> true}) do |form| %>
  <p>
    <b>コメント:</b><br />
    <%= form.text_field("comment") %><br/>
  </p>
  <p>
    <b>画像:</b><br />
    <%= form.file_field("uploaded_picture") %><br/>
  </p>
  <%= submit_tag("upload") %>
<% end %>

・app/view/hoge/show.rhtml

<h3><%= @picture.comment %></h3>
<% if @picture.file_url != nil then %>
	<img src="<%= @picture.file_url %>" alt="file">
	<img src="/images/jukebox.jpeg" alt="file">
<% end %>