おいちゃんと呼ばれています

ウェブ技術や日々考えたことなどを綴っていきます

Paperclip と CarrierWave を結構マジメに比較してみた

仕事で Rails の画像アップロードライブラリを選定することになって、この分野のメジャーどころ Paperclip と CarrierWave を較べてみました。仕事で使うライブラリは一旦選ぶとそうそう簡単には乗り換えられないということもあって結構マジメに選んだつもりです。

-thoughtbot/paperclip -carrierwaveuploader/carrierwave -The Ruby Toolbox - Rails File Uploads

どちらも RailsCasts がチュートリアル(?)を用意してくれているので、それをやった後、それぞれプラス 2時間くらいゴニョゴニョしてみた結果をメモしておきます。

-#134 Paperclip - RailsCasts -ASCIIcasts - “Episode 253 - CarrierWaveでファイルのアップロード”

なお、環境は下記のとおりです。

-Ruby 2.0.0-p247 -Rails 4.0.0 -paperclip 3.5.1 -carrierwave 0.9.0 -rmagick 2.13.2

**Paperclip と CarrierWave を比較してみた -1. ざっくりとした結論 -2. 大きな違い -3. 画像リサイズ等 -4. 画像の保存先指定 -5. Paperclip のその他の長所 -6. CarrierWave のその他の長所 -7. ウェブ上での情報量 -8. 結局どちらを選んだのか? <<

*1. ざっくりとした結論

細かいハナシは後回しにして、ざっくり結論を先に言ってしまうと、下記のような感じです。

-いろいろ凝ったことをやりたいなら、多機能な CarrierWave -シンプルな機能を手早く実装したいなら Paperclip

*2. 大きな違い

大きな違いが 2つありまして。いずれも RailsCasts が言及してくれています。

-ASCIIcasts - “Episode 253 - CarrierWaveでファイルのアップロード”

ひとつめの違い。

CarrierWave は Paperclip と比較してより柔軟な機能を提供します。Rack に対応しているため、RailsSinatra など Rack ベースの Ruby アプリケーションで動作し、ActiveRecord、DataMapper、 Mongoid など多くの ORM をサポートしています。 <<

これはまあ、そのまんまですね。

もうひとつの違い。

もうひとつ CarrierWave と Paperclip の大きな違いとして、CarrierWave は添付ファイルとその処理ロジックを別の Uploader クラス内に持ちます。このため、添付ファイルがアプリケーションのモデルクラスと混ざって混乱するということがありません。 <<

これはどういう事かといいますと、例えばアップロードした後に画像をリサイズをしたり、画像の保存先を指定したい場合、Paperclip だとその設定をモデルに書きます。

|ruby| class Video < ActiveRecord::Base has_attached_file :photo, :styles => { :small => "150x150>" }, :url => "/system/:attachment/:id/:style/:basename.:extension", :path => ":rails_root/public/system/:attachment/:id/:style/:basename.:extension" ... ||<

しかし、この設定を別の Actress というモデルでも使いたい場合は、コピペしないといけなくなります。一方で、CarrierWave ではモデルとは別の Uploader クラスに書くので複数のモデルで使い回すことができます(もちろん、Video と Actress とでそれぞれ別の Uploader を割り当てることもできます)

*3. 画像リサイズ等

今回求めていた要件は下記のとおりです。

-アップロードした画像をリサイズすることができる(縦横比そのまま) -長方形の画像を、中央を起点にして正方形に切り取ることができる -複数のバージョンの画像を保持できる <<

これらは、Paperclip と CarrierWave いずれでも実現できます。しかもカンタンに。ただ、CarrierWave では RMagick を使うことができるので、画像処理でちょっと凝ったことをやろうとするとこちらに軍配が上がると思います。

しかし、画像のリサイズについては、画像を保存するときよりも画像を表示させるときに指定できた方が良いと思われるので、その方向に寄せたいと考えています。デザインが変われば必要とされる画像のサイズも変わりますし。

そして、画像を表示させるときにリサイズを行う技術は、今回対象としているライブラリは関係ないです。この分野の技術については、下記のクックパッドの資料が参考になります。

-料理を楽しくする画像配信システム

*4. 画像の保存先指定

どちらのライブラリでも画像の保存先を指定できます。Amazon S3 も含めて。CarrierWave の方は画像のキャッシュ先も指定できるので、フォームが送信されたときにモデルで検証エラーが発生してフォームが再表示されても、キャッシュされた画像を表示できます。

細かいことを言うと、複数のバージョンの画像を保存する場合は、Paperclip だとデフォルトでバージョンごとにディレクトリが分けられています。あるバージョンが不要になったときにバッサリ削除しやすいのでラクでした。

CarrierWave はデフォルトでは、バージョンが「small_sample.jpg」のように接頭語として付きます。バージョンごとにディレクトリを分けることはできるのですが、結局、接頭語を外すやり方がわからず困りました。

*5. Paperclip のその他の長所

使用したことはないですが、Paperclip の README には PDF のアップロードにも対応している旨が書かれています。

また、前述のとおり、今回 RailsCasts のチュートリアル + 画像の加工や画像の保存先指定などをやってみたのですが、Paperclip の方があまり引っ掛からずにすんなりいけた印象があります。

*6. CarrierWave のその他の長所

一方、いろんな小技はやはり後発の CarrierWave の方が得意のようです。

-画像をアップロードする代わりに URL を指定して画像を登録する -フォームにチェックボックスを追加して、ユーザが画像を削除できるようにする -既存のバージョンの画像から別のバージョンの画像を作成する

あと、Paperclip からの移行も用意されているようです(しかし、大抵こういうのってハマりますよね。。)

*7. ウェブ上での情報量

どちらのライブラリも広く利用されているものなので、英語、日本語両方について、ググればそれなりの量と質の情報を見つけることができました。

*8. 結局どちらを選んだのか?

前述のとおり、今回は仕事の関係で選んでいたのですが、下記の理由から Paperclip の方を選びました。

-画像加工等については、モデルと 1対1 の関係でかまわない -画像の凝った加工等は必要ない -シンプルな機能であれば Paperclip の方が手早く実装できる感触があった(とにかくスピードを求められている案件なのです。。) -社内の他のサービスで利用実績がある --画像の加工等には凝った要件はないが、画像の保存先等をいろいろとカスタマイズする際に気軽に訊ける --社内で知識を蓄積・共有できる

一方で、個人でやっている Web サイト babyshark や h300 では、

-画像加工やその他の設定について、複数のモデルで使い回す -いろいろと小技が使える方が良い

ので、近いうちに CarrierWave の方を導入しようと考えています。

以上です。参考になりましたら幸いです。ではでは。

*参考リンク

-thoughtbot/paperclip -carrierwaveuploader/carrierwave -The Ruby Toolbox - Rails File Uploads -#134 Paperclip - RailsCasts -ASCIIcasts - “Episode 253 - CarrierWaveでファイルのアップロード”