RailsアプリにPaperclipを使って画像アップロード機能をつける

目次

  1. 環境
  2. インストール
  3. 実装
  4. テスト
  5. 参考

環境

  • Ruby: 2.0.0-p0
  • Rails: 3.2.13
  • paperclip: 3.4.1

インストール

ImageMagickが必要なので, 確認して無かったらインストールしておく.

which convert # 無かったら次でインストール
brew install imagemagick

後はいつも通り, Gemfileにgem 'paperclip'を追加してbundle installすればよい.

実装

既存のUserモデルにアイコンとしてavatarを追加し, 登録, 編集, 表示が出来るようにする.

まずは, rails g paperclip user avatarしてrake db:migrateしておく.

生成されたマイグレーションファイルの中身はこんな感じ.

class AddAttachmentAvatarToUsers < ActiveRecord::Migration
  def self.up
    change_table :users do |t|
      t.attachment :avatar
    end
  end

  def self.down
    drop_attached_file :users, :avatar
  end
end

後は実装していく. app/models/user.rbに以下を追加.

class User < ActiveRecord::Base
  attr_accessible :avatar
  has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/system/missing/:style/missing.jpg"

  validates_attachment :avatar, presence: true,
    content_type: { content_type: ["image/jpg", "image/png"] },
    size: { less_than: 2.megabytes }
end

app/views/users/_form.html.erbでは, <%= form_for(@user) do |f| %>の中に

<div class="field">
  <%= f.label :avatar %><br />
  <%= f.file_field :avatar %>
</div>

を追加. app/views/users/show.html.erbでは, 画像を表示させたい箇所に

<p>
  <%= image_tag @user.avatar.url(:thumb) %>
</p>

を追加. これだけで登録, 編集, 表示が出来るようになった.

テスト

まず, spec/spec_helper.rbに以下を追加しておく.

require "paperclip/matchers"

RSpec.configure do |config|
  config.include Paperclip::Shoulda::Matchers
end

spec/models/user_spec.rbはこんな感じ.

describe User do
  it { should have_attached_file(:avatar) }
  it { should validate_attachment_presence(:avatar) }
  it { should validate_attachment_content_type(:avatar).
                allowing('image/jpg', 'image/png') }
  it { should validate_attachment_size(:avatar).
                less_than(2.megabytes) }
end

spec/controllers/users_controller_spec.rbはこんな感じになる.

describe UsersController do
  def valid_attributes
    { username: "MyString",
      email: "MyString",
      avatar_file_name: '私のテキスト_n',
      avatar_content_type: 'image/png',
      avatar_file_size: 1,
      avatar_updated_at: '2011-07-13 14:53:38'
    }
  end

  def valid_session
    {}
  end

  describe "GET show" do
    it "assigns the requested user as @user" do
      user = User.create! valid_attributes
      get :show, {:id => user.to_param}, valid_session
      assigns(:user).should eq(user)
    end
  end
end

参考