読者です 読者をやめる 読者になる 読者になる

ハッカーを目指す白Tのブログ

夏は白のTシャツを着ています。ラジオが好きです。(ラジオネーム: 隠れキリジダン)

RailsのPaperclipについてまとめてみた

Rails

Railsを使って、SNS上で共有された画像を活用したWEBサービスを作ろうと思い、画像ファイルの管理を担うgem、Paperclipについて調べてみた。

1. Paperclipとは

thoughtbot/paperclip · GitHub
Paperclipは、RailsActiveRecord用のライブラリである。Railsのアプリケーションで、ユーザーがアップロードした画像等のファイルについての煩雑な設定、すなわち、保存や削除などの設定を簡単に行うことができるようになる。
Paperclipは、ImageMagick(http://www.imagemagick.org/)と共に使うことを前提としていて、アップロードした画像を縦横比そのままでリサイズしたり、長方形の画像を、中央を起点にして正方形に切り取ったりすることができる。以下、Paperclipの使い方について説明する。

2. Paperclip::ClassMethods#has_attached_file

まず、migrationで生成した添付ファイルの保存先(attachment)へのパスをモデルに伝えるメソッド、has_attached_fileについて説明する。

has_attached_file( name, options = {} )

#以下はsample、モデルに記述する
has_attached_file :sample_image, :url =>  "/:class/:attachment/:id/:style_:filename",
                                            :styles => { :normal => "100x100#", :large => '200x200#' },
                                            :storage => :s3

このクラスメソッドは、前述のとおり、呼び出されたクラスに対して添付ファイルが保存されるべきパスを伝えるものである。添付ファイルを管理するPaperclip::Attachment オブジェクトを返す。Railsで、他のカラムに属性を定義するのと同じように添付ファイルについても、属性のような情報を定義できるようにした。新しいファイルがアップロードされると、サムネイルが作られ、saveメソッドが呼び出されることで保存される。以下、このメソッドのオプションでできることを一覧で示す。

has_attached_fileのoptionsでできること一覧

1. 添付ファイルを保存するパスを指定

:url => "/:class/:attachment/:id/:style_:filename"

urlオプションに対して、ファイルの保存先を絶対パスで指定。ドメインまで指定する必要はない。デフォルトは “/system/:attachment/:id/:style/:filename”.
また、ブラウザで表示するURLを指定することも可能。その場合、以下のようにURLをpathオプションに渡す。

path: "#{Rails.root}/public/system/:class/:id/:attachment/:style.:extension"

2. 添付ファイルがない場合のデフォルト画像のパスを指定

default_url:  "/images/default_:style_avatar.png"
User.new.avatar_url(:small) # => "/images/default_small_avatar.png"

default_urlオプションにパスを渡す。デフォルトは、“/:attachment/:style/missing.png

3. サムネイルのスタイルの指定

:styles => { :normal => "100x100#", :large => '200x200#' }

このstylesオプションに、スタイル名がkeyで、指定したいスタイルがvalueのhashを渡す。スタイルの指定方法については、ImageMagickのサイトに記載されている(www.imagemagick.org/script/command-line-options.php#resize). ImageMagickのスタイルの設定に加え、さらに “#” オプションが追加されていて、 これは指定されたサイズに最大限fitするように画像をリサイズし、中央を起点に不要な部分を切り取るという設定である。(example: “50x50#”)、 デフォルトでは、サムネイルが生成されない.

4. デフォルトのURLで使われるサムネイルのスタイル名の指定

has_attached_file :avatar, :styles => { :normal => "100x100#", :large => '200x200#' },
:default_style => :normal
user.avatar.url # => "/avatars/23/normal_me.png"

default_styleオプションに、stylesオプションで指定したスタイル名を渡す。つまるところ、ユーザーがファイルをアップロードする際に、スタイル名を指定しなかった場合に適用されるスタイルのスタイル名を指定できるオプションである。

5. ファイルを添付出来ない場合のコマンドラインエラーを表示するか否かの指定

whiny : false

whinyオプションに真偽値を渡す。デフォルトはtrue。コマンドラインエラーでアップロードファイルをpost_process出来ない場合、エラーを表示するか指定できる。

6. どのように画像を変換するか指定

has_attached_file :avatar, :styles => { :large => "300x300", :negative => "100x100" }
:convert_options => {
:all => "-strip",
:negative => "-negate"
}

convert_optionsオプションに、スタイル名がkeyで、画像の変換オプションがvalueのhashを渡す。画像の変換オプションの例として、'-strip' オプションは、画像からExif dataを取り除くために使われ、 “-depth 8”オプションは、ビット深度を指定するのに使われる。詳しくは、ImageMagickの convert documentation(ImageMagick: Command-line Tools: Convert) に記載。 allをkeyとするhashのvalueにoptionを指定することで、作成される全てのスタイルのサムネイルに適用するオプションを指定できる。

7. ファイルが保存されるストレージの指定

storage : :s3

storageオプションに、ストレージ名を渡す。 ストレージの選択肢としては 、:filesystem または、 :s3がある。 デフォルトは、 :filesystem.

3. 添付ファイルに対するvalidation

Paperclip::ClassMethods#validates_attachment_content_type

このクラスメソッドは、添付ファイルのファイル形式に対して、ActiveRecordのようなvalidationをかけることができる。

validates_attachment_content_type :sample_image, content_type:  ["image/jpeg", "image/gif", "image/png"],
                                                                                 message: 'ファイル形式が不正です。'

content_typeオプションに、許可するファイル形式を一つまたは、複数を配列で渡す。各typeは、String または a Regexpで指定可能. IEは、予期せぬタイプでファイルがアップロードされる場合があるから注意が必要。たとえば、JPEGはimage/pipeg、PNGはimage/x-pngでアップロードされるので、マッチする時気をつけよう。デフォルトは全てのタイプを許可。
messageオプションに、アップロードできないcontent type のfile がアップロードされた時に表示されるメッセージを渡す。

Paperclip::ClassMethods#validates_attachment_presence

このクラスメソッドは、添付ファイルの有無に対して、ActiveRecordのようなvalidationをかけることができる。

validates_attachment_presence :sample_image

Paperclip::ClassMethods#validates_attachment_size

このクラスメソッドは、添付ファイルのサイズに対して、ActiveRecordのようなvalidationをかけることができる。

validates_attachment_size :sample_image, :less_than=>1.megabyte

inオプションで、許可するファイルサイズの範囲を指定できる。
less_thanオプションで、許可する最大のファイルサイズを指定できる。
greater_thanオプションで、許可する最小のファイルサイズを指定できる。
messageオプションで、表示するエラーメッセージを指定できる。

添付ファイルの削除、論理削除

添付ファイルの削除

添付ファイルを削除するには、attributeをnilにして、saveすると削除される。

@user.avatar = nil
@user.save

また、添付ファイルが紐づくオブジェクトが削除されると、添付ファイルも削除される。

添付ファイルの論理削除

acts_as_paranoid, paranoia 等の論理削除用のgemと連動して、論理削除が行えるように、Paperclipではオプションが用意されている。
has_attached_fileのメソッドのoptionで、preserve_filesをtrueにすれば、添付ファルの論理削除が正常に行われる.

has_attached_file :some_attachment, {
:preserve_files => "true",
}

s3の設定

アマゾンの S3 に保存する際は、まず aws-sdk というgem を使う。

#Gemfile に、以下の行を追加。
gem 'aws-sdk', '~> 1.5.7'

その後、has_attached_file のオプションで、s3を指定。詳しくは、Paperclip::Storage::S3 documentation(Module: Paperclip::Storage::S3 — Documentation for paperclip (4.2.0))。

Paperclipと他のgemの比較

Paperclipと他のgemの比較については、
Paperclip と CarrierWave を結構マジメに比較してみた - 彼女からは、おいちゃんと呼ばれています

参照サイト:
Module: Paperclip::ClassMethods — Documentation for paperclip (2.3.8)
RailsでPaperclipを使ってみたメモ [俺の備忘録]

以上