今さらRails3メモ - 番外編その1: Paperclip and Dragonfly -
アップロード画像は変遷がいろいろ激しいみたい
画像をアップロードしてそれを表示に利用するのはとてもよくある処理だと思うんだけど、ゼロから実装するのは意外に面倒くさい。でも Rails には便利な plugin があるので大丈夫。
歴史的なことは知らないんだけど、最近は
の二択くらいな感じみたい。どちらも簡単に扱えるけどどっちかというと Dragonfly の方がより簡単で好きかも。ただし今のところ Dragonfly の方が情報は少ないけど。
Paperclip
migration
README から抜粋すると以下の field を持つテーブルが必要らしい。らしいっていうか、実際試してみたんだけど、このエントリ書くまで日が空きすぎて忘れてしまった。
class AddAvatarColumnsToUser < ActiveRecord::Migration
def self.up
add_column :users, :avatar_file_name, :string
add_column :users, :avatar_content_type, :string
add_column :users, :avatar_file_size, :integer
add_column :users, :avatar_updated_at, :datetime
end
def self.down
remove_column :users, :avatar_file_name
remove_column :users, :avatar_content_type
remove_column :users, :avatar_file_size
remove_column :users, :avatar_updated_at
end
end
Model
上の migration に対応する Model はこうなる。
class User < ActiveRecord::Base
has_attached_file :avatar
...
end
ここで画像用の attribute は avatar になって、file_name やらなんやらは meta data としていい具合に処理してくれるようになる。
View
こんな感じ。
<%= image_tag @user.avatar.url %>
<%= image_tag @user.avatar.url(:medium) %>
<%= image_tag @user.avatar.url(:thumb) %>
今回の例は User モデルに avatar 関連の attribute をそのまま載せているが、分離して association でも処理できる。
form 側はこんな感じ。
<% form_for :user, @user, :url => user_path,
:html => { :multipart => true } do |form| %>
<%= form.file_field :avatar %>
<% end %>
単に file_field に当てはめるだけ。
参考
- websymphony/Rails3-Paperclip-Uploadify at master - GitHub
- association を使った簡単な例
- paperclip の保存ディレクトリ名あるいはファイル名をid連番ではなく、MD5とかSHA1のハッシュ値にするメモ - 超自己満足プログラミング
- [Rails] PaperClipを使って本番の時だけAmazon S3を使う - func09
- [rails] paperclipでAmazon CloudFrontを使う - func09
Dragonfly
http://markevans.github.com/dragonfly/
Paperclip のようにはドキュメントや紹介記事を見かけないけど、コードを覗いていくと storage として file, mongo, s3 が使えるみたい。
下準備
config/initializers/dragonfly.rb
require 'dragonfly/rails/images'
migration
最低限一つだけ field があればよいみたい。
class MyMigration < ActiveRecord::Migration
def self.up
add_column :albums, :cover_image_uid, :string
end
def self.down
remove_column :albums, :cover_image_uid
end
end
Model 上でどんな attribute に画像を紐づけるか決めて、
#{attribute}_uid
があれば ok.
Model
上の migration に対応する最低限の Model の記述は
class Album
image_accessor :cover_image
end
image_accessor で attribute を指定するだけ。すると以下のような感じで meta data を取れる。
@album.cover_image.width
@album.cover_image.height
@album.cover_image.number_of_colours
@album.cover_image.mime_type
View
<%= image.caption %></th>
<%= image_tag( image.photo.process(:thumb, '240x240#').url,
{:size => '240x240', :alt => image.caption} ) %>
こんな風に書ける。
form 側は
<% form_for @album, :html => {:multipart => true} do |f| %>
...
<%= f.file_field :cover_image %>
...
<% end %>
同じ要領ですな。
注意
当たり前だけど image_tag を生成すること。でないと表示されない。