概要
gem carrierwave のREADME を翻訳しました。
-
翻訳について
-
ライセンスについて
- carrierwave のライセンスと同様のライセンスに従います。
CarrierWave
この gem は Ruby アプリケーションからファイルをアップロードするシンプルかつ強力な方法を提供します。
この gem は Ruby on Rails のような Rack を基にしたウェブアプリケーションとともによく動作します。
インフォーメーション
- RDoc ドキュメントは RubyDoc.info で閲覧できます。
- ソースコードは Githubで閲覧できます。
- 詳細情報、既知の制限事項、ハウツーは wiki で閲覧できます。
お願い
- 質問がある際は、Stack Overflow のコミュニティに助けを求めてください。issue tracker では利用方法の質問を投稿しないようにしてください。
- issue tracker にバグを報告してください。ただし、まず最初に wiki の "getting help" セクションを読んでください。
インストール
最新バージョンのインストール。
$ gem install carrierwave
Rails では下記を Gemfile に追加してください。
gem 'carrierwave', '~> 2.0'
最後に、サーバーを再起動して変更を適用してください。
現在のバージョン 2.0 では、CarrierWave は Rails 5.0 以上かつ Ruby 2.2 を必要とします。もし Rails 4 を使用している場合は 1.x バージョンを利用してください。
はじめに
まずは、uploader を生成します。
rails generate uploader Avatar
それによりファイルが作成されます。
app/uploaders/avatar_uploader.rb
アップローダーをどのようにカスタマイズできるかを知るためにこのファイルを確認してください。ファイルは下記のようになっています。
class AvatarUploader < CarrierWave::Uploader::Base
storage :file
end
下記のようにアップローダークラスを使用してファイルの保存と取得を行うことができます。
uploader = AvatarUploader.new
uploader.store!(my_file)
uploader.retrieve_from_store!('my_file.png')
CarrierWave は永続的な保存のための ストア
と一時的な保存のための キャッシュ
を提供します。ファイルシステムとクラウドストレージを含む異なる保存方法を使用することができます。
ほとんどの場合、ORM と一緒に CarrierWave を使用することになると思います。モデルのカラムにアップローダをマウントするのは非常に簡単なので、ファイルを割り当てるだけで、次のようなことができます。
ActiveRecord
ORM を読み込んだ後に CarrierWave を読み込んでいることを確認してください。そうしないと手動で関連する拡張機能を要求する必要がでてきます。
require 'carrierwave/orm/activerecord'
マイグレーションを作成することでアップローダーをマウントしたいモデルに string のカラムを追加してください。
rails g migration add_avatar_to_users avatar:string
rails db:migrate
モデルファイルを開いてアップローダーをマウントしてください。
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
アトリビュートにファイルを割り当てるとそのファイルはキャッシュされます。そしてレコードが保存されるときに自動的にそのファイルは保存されます。
u = User.new
u.avatar = params[:file] # このようにファイルを割り当てる
# あるいは下記のようにも割り当てることができる
File.open('somewhere') do |f|
u.avatar = f
end
u.save!
u.avatar.url # => '/url/to/file.png'
u.avatar.current_path # => 'path/to/file.png'
u.avatar_identifier # => 'file.png'
注意: たとえアトリビュートに関連付けられた写真がなくても u.avatar
が nil を返すことはありません。
モデルに写真が保存されたかどうかを確認するためには、u.avatar.file.nil?
を使用してください。
DataMapper, Mongoid, Sequel
他の ORM のサポートはそれぞれの gem に分離されています。
wiki により多くの拡張機能を掲載しています。
複数ファイルのアップロード
複数ファイルのアップロードにおいても CarrierWave は便利なサポートを提供しています。
ActiveRecord
配列を保存できるカラムを追加してください。たとえばこのカラムは配列でもよいですし、JSON カラムにすることもできます。どのような選択肢があるかはデータベースのサポートに依存します。たとえば、下記のようなマイグレーションを作成します。
ActiveRecord の json タイプのサポートがあるデータベース(例: PostgreSQL, MySQL)
rails g migration add_avatars_to_users avatars:json
rails db:migrate
ActiveRecord の json タイプのサポートがないデータベース(例: SQLite)
rails g migration add_avatars_to_users avatars:string
rails db:migrate
注意: JSON データタイプは SQLite アダプタには存在しないので、モデルの中でシリアライズされる string データタイプを使うことができます。
モデルファイルを開いてアップローダーをマウントしてください。
class User < ActiveRecord::Base
mount_uploaders :avatars, AvatarUploader
serialize :avatars, JSON # SQLite を使用している場合はこの行を追加してください
end
複数ファイルのアップロード時にエラーを避けるために、mount_uploader
ではなく s
をつけて mount_uploaders
と記載してアップローダーをマウントしていることを確認してください。
複数ファイル用のフィールドとしてファイルインプットフィールドが設定されていることを確認してください。たとえば、Rails では下記のようにすることができます。
<%= form.file_field :avatars, multiple: true %>
また、アップロード用のコントローラーが複数ファイル用のアトリビュートを許可し、ハッシュ内の空配列を指していることを確認してください。下記が例となります。
params.require(:user).permit(:email, :first_name, :last_name, {avatars: []})
アップロードダイアログで複数ファイルを選択(例: SHIFT+SELECT)することができ、レコードが保存されるときにそれらのファイルも自動的に保存されます。
u = User.new(params[:user])
u.save!
u.avatars[0].url # => '/url/to/file.png'
u.avatars[0].current_path # => 'path/to/file.png'
u.avatars[0].identifier # => 'file.png'
新しいファイルをアップロードするときに既存のファイルを残しておきたいときは、下記のようにします。
<% user.avatars.each do |avatar| %>
<%= hidden_field :user, :avatars, multiple: true, value: avatar.identifier %>
<% end %>
<%= form.file_field :avatars, multiple: true %>
hidden_field
を記録することでアバターの並び順もサポートされます。jQuery UI Sortable を使用した例はこちらです。
保存ディレクトリの変更
アップロードファイルが保存される場所を変更するときは、store_dir
メソッドをオーバーライドしてください。
class MyUploader < CarrierWave::Uploader::Base
def store_dir
'public/my/upload/directory'
end
end
このメソッドは Amazon S3 や Rackspace クラウドファイルでもファイルストレージとして動作します。
これはファイルストレージだけでなく、Amazon S3 や Rackspace Cloud Files も同様に動作します。もしルートレベルでファイルを保存したいときは store_dir
を nil
として定義してください。
もしプロジェクトルートフォルダの外にファイルを保存するときは、同様の方法で cache_dir
を定義してください。
class MyUploader < CarrierWave::Uploader::Base
def cache_dir
'/tmp/projectname-cache'
end
end
セキュア・アップロード
PHP ファイルや他のスクリプトファイルなど、間違った場所にアップロードすると危険なファイルがあるかもしれません。CarrierWave では拡張子とコンテントタイプのホワイトリストを指定することができます。
アップローダーをマウントしたとき、ファイルの拡張子が不正なものだったらレコードが無効になるか、エラーが起きます。
class MyUploader < CarrierWave::Uploader::Base
def extension_whitelist
%w(jpg jpeg gif png)
end
end
コンテントタイプでも同じことをできます。
イメージのみ許可するアップローダーが必要なときは、下記のように記述できます。
class MyUploader < CarrierWave::Uploader::Base
def content_type_whitelist
/image\//
end
end
コンテントタイプを拒否するブラックリストを使用することもできます。
JSON ファイルを拒否するアップローダーが必要なときは、下記のように記述できます。
class NoJsonUploader < CarrierWave::Uploader::Base
def content_type_blacklist
['application/text', 'application/json']
end
end
CVE-2016-3714 (ImageTragick)
このバージョンの CarrierWave は CVE-2016-3714 脆弱性を軽減することができます。しかし、効果的な保護のために content_type_whitelist を必ず設定するようにしてください。そして ImageMagick のデフォルト SVG 移譲を無効にするか、あるいは SVG の処理のために RSVG 移譲を使用するかのどちらかを必ず行ってください。
image のみにコンテントタイプを制限することが有効なホワイトリストです。そしてこのホワイトリストによって CVE は軽減されます。
class MyUploader < CarrierWave::Uploader::Base
def content_type_whitelist
[/image\//]
end
end
警告: content_type_whitelist
は CarrierWave がサポートするホワイトリストあるいはブラックリストの唯一の形式で、CVE-2016-3714 を効果的に軽減します。extension_whitelist
はファイルヘッダを見ないので、脆弱性を軽減しません。
ファイル名とユニコード文字
注意すべきもう一つのセキュリティの問題はファイル名です(Ruby On Rails Security Guideをご覧ください)。
デフォルトでは、CarrierWave はファイル名においてホワイトリストとして登録されている文字として、英字・アラビア数字・いくつかの記号のみを提供しています。もしローカルな文字(キリル文字、ダイアクリティック付きの文字など)をサポートしたいときは、sanitize_regexp
メソッドをオーバーライドする必要があります。このメソッドは許可されていない文字すべてにマッチする正規表現を返す必要があります。
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
また、非ラテン文字を許可することでサードパーティプラグインやクライアントサイドソフトウェアとの互換性の問題を引き起こさないようにしてください。
コンテントタイプの設定
v0.11.0 では、mime-types
gem は実行時の依存関係に含まれており、コンテントタイプは自動的に設定されます。
手動で設定する必要はありません。
バージョン追加
同じファイルの異なるバージョンを追加したくなることがよくあります。典型的な例は画像のサムネイルです。CarrierWave にはこのサポートが組み込まれています。
注意: 画像をリサイズするには Imagemagick がインストールされている必要があります。
MiniMagick の代わりに RMagick を使用するように書いてあるドキュメントもありますが、MiniMagick の使用を推奨します。
OSX で homebrew を用いて Imagemagick をインストールする方法は下記の通りです。
$ brew install imagemagick
class MyUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process resize_to_fit: [800, 800]
version :thumb do
process resize_to_fill: [200,200]
end
end
このアップローダを使用した場合、アップロードされた画像は800ピクセル×800ピクセル以下の大きさになります。元々のアスペクト比はそのままです。
次に :thumb
という名前のバージョンが作成され、これは正確に 200 x 200 ピクセルに縮小されます。サムネイルは resize_to_fill
メソッドを使用して、指定した幅と高さの要求に応じます。リサイズされる画像のアスペクト比がトリミングを必要とするときのみ、トリミングを行います。
上述のアップローダーは下記のように使用されます。
uploader = AvatarUploader.new
uploader.store!(my_file) # size: 1024x768
uploader.url # => '/url/to/my_file.png' # size: 800x800
uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
重要なのは、バージョンが作成される前にプロセスが呼び出されることです。これにより、処理コストを削減することができます。
プロセスメソッド: mini_magick
convert
画像のエンコードフォーマットを与えられたフォーマットに変更する(例: jpg)。
resize_to_limit
オリジナルのアスペクト比は維持しつつ、指定した大きさに収まるように画像をリサイズします。指定した大きさより画像が大きいときのみ画像をリサイズします。結果として得られる画像は、指定された値よりも短くなったり狭くなったりすることがありますが、指定された値よりも大きくなることはありません。
resize_to_fit
オリジナルのアスペクト比は維持しつつ、指定した大きさに収まるように画像をリサイズします。リサイズ後の画像は、指定された値よりも短くなったり狭くなったりすることがありますが、指定された値よりも大きくなることはありません。
resize_to_fill
オリジナルのアスペクト比は維持しつつ、指定した大きさに収まるように画像をリサイズします。必要に応じて、画像を拡大してトリミングします。たとえば、"Center" や "NorthEast" のようにオプションで "gravity" を指定することもできます。
resize_and_pad
オリジナルのアスペクト比は維持しつつ、指定した大きさに収まるように画像をリサイズします。必要に応じて、指定された色で残りの領域をパッドします。色のデフォルトは gif と png では透明で、jpeg では白です。上述のようにオプションで "gravity" を指定することもできます。
詳細は carrierwave/processing/mini_magick.rb
をご覧ください。
ネストされたバージョン
バージョンの中でバージョンをネストすることが可能です。
class MyUploader < CarrierWave::Uploader::Base
version :animal do
version :human
version :monkey
version :llama
end
end
条件付きのバージョン
モデル内の特定のプロパティや画像自体に基づいたバージョンの作成を制限したい場合があります。
class MyUploader < CarrierWave::Uploader::Base
version :human, if: :is_human?
version :monkey, if: :is_monkey?
version :banner, if: :is_landscape?
private
def is_human? picture
model.can_program?(:ruby)
end
def is_monkey? picture
model.favorite_food == 'banana'
end
def is_landscape? picture
image = MiniMagick::Image.new(picture.path)
image[:width] > image[:height]
end
end
model
変数はアップローダーがアタッチされる先のインスタンスオブジェクトを示しています。
既存バージョンからのバージョン作成
パフォーマンス上の理由で、オリジナルファイルを使用する代わりに既存バージョンからバージョンを作成することが便利です。もしアップローダーがいくつかのバージョンを生成し、最後に生成されたバージョンより次に生成するバージョンの画像サイズが小さいときは、オリジナルファイルより小さくすでに処理済みの画像から次のバージョンを生成すると処理時間が短くなります。
class MyUploader < CarrierWave::Uploader::Base
version :thumb do
process resize_to_fill: [280, 280]
end
version :small_thumb, from_version: :thumb do
process resize_to_fill: [20, 20]
end
end
オプション :from_version
はオリジナルバージョンの代わりに :thumb
バージョンでキャッシュされたファイルを使用し、処理速度が早くなる可能性があります。
再表示が起こるときのアップロードの実行
バリデーションが失敗したときにアップロードしたファイルが消えることに気をつけることも多いと思います。CarrierWave はそのような場合でもアップロードしたファイルの保存を簡単にする機能を持っています。user
モデルが avatar
ファイルをマウントしたアップローダーを持っているとき、avatar_cache
と名付けた隠れフィールドを追加してください(必要であれば avatar_cache を attr_accessible に追加してください)。Rails では下記のようになります。
<%= form_for @user, html: { multipart: true } do |f| %>
<p>
<label>My Avatar</label>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</p>
<% end %>
ファイルがアップロードされたことをユーザーに示すのは良いアイデアかもしれませんが、画像の場合は、小さなサムネイルが良い指標になります。
<%= form_for @user, html: { multipart: true } do |f| %>
<p>
<label>My Avatar</label>
<%= image_tag(@user.avatar_url) if @user.avatar? %>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</p>
<% end %>
アップロードしたファイルの削除
マウントされたアップローダーで以前にアップロードされたファイルを削除したい場合は、チェックボックスをフォームに追加することで簡単に削除することができます。
<%= form_for @user, html: { multipart: true } do |f| %>
<p>
<label>My Avatar</label>
<%= image_tag(@user.avatar_url) if @user.avatar? %>
<%= f.file_field :avatar %>
</p>
<p>
<label>
<%= f.check_box :remove_avatar %>
Remove avatar
</label>
</p>
<% end %>
手動でファイルを削除したいときは、remove_avatar!
メソッドを呼び出してからオブジェクトを保存してください。
@user.remove_avatar!
@user.save
#=> true
リモートロケーションからのファイルアップロード
URL によってインターネット上の場所からファイルをアップロードすることは便利です。CarrierWave はこれをただ適切なアトリビュートをフォームに追加するというシンプルな方法で実現します。
<%= form_for @user, html: { multipart: true } do |f| %>
<p>
<label>My Avatar URL:</label>
<%= image_tag(@user.avatar_url) if @user.avatar? %>
<%= f.text_field :remote_avatar_url %>
</p>
<% end %>
ActiveRecordを使用している場合、CarrierWave は無効な URL とダウンロードの失敗をアトリビュートのバリデーションエラーで自動的に表示します。そうでない場合や CarrierWave の validate_download
オプションを無効にしている場合は、これらのエラーを自分で処理する必要があります。
デフォルト URL の提供
多くの場合、特に CarrierWave を画像と一緒に使うとき、デフォルト URL やファイルがアップロードされなかったときのためのフォールバックを提供するのは良い考えです。アップローダーの default_url
メソッドをオーバーライドすることでこれを簡単に行うことができます。
class MyUploader < CarrierWave::Uploader::Base
def default_url(*args)
"/images/fallback/" + [version_name, "default.png"].compact.join('_')
end
end
Rails のアセットパイプラインを使用しているときは下記のように記載します。
class MyUploader < CarrierWave::Uploader::Base
def default_url(*args)
ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
end
end
バージョンの再作成
事後にバージョンを変更したり新しく追加したくなることがあると思います。recreate_versions!
メソッドを使用してベースファイルからバージョンを再作成することができます。これは単純な方法を用いており、指定バージョン、あるいは引数が指定されない場合は全てのバージョンを再アップロードし処理を行ないます。
ランダムな一意のファイル名を生成するとき、recreate_versions!
メソッドの使用後にモデルの save!
メソッドを呼び出す必要があります。なぜなら recreate_versions!
メソッドはデータベースに新しいファイル名を保存しないからです。save!
メソッドを呼び出すことでデータベースとファイルシステムが一致せずに動作することを防ぐことをできます。
instance = MyUploader.new
instance.recreate_versions!(:thumb, :large)
マウントされたアップローダーでは下記のように記述します。
User.find_each do |user|
user.avatar.recreate_versions!
end
注意: recreate_versions!
メソッドは画像のないレコードでは例外を起こします。これを避けるためには、レコードが画像を持っているかよく調べる、あるいはブロック内で画像が存在しているかどうかを確認してください。ActiveRecord を使用している場合に、user avatar に対してバージョンの再作成を行うときは下記のようになります。
User.find_each do |user|
user.avatar.recreate_versions! if user.avatar?
end
CarrierWave の設定
CarrierWave は幅広い設定をオプションで行うことができ、グローバルにも各アップローダーごとにもオプションを設定することができます。
CarrierWave.configure do |config|
config.permissions = 0666
config.directory_permissions = 0777
config.storage = :file
end
あるいは下記のように記述できます。
class AvatarUploader < CarrierWave::Uploader::Base
permissions 0777
end
Rails を使用している場合は設定のためにイニシャライザを作成してください。
config/initializers/carrierwave.rb
development 環境でエラーを無視したくない場合は、環境ファイルの下記の設定を変更することができます。
CarrierWave.configure do |config|
config.ignore_integrity_errors = false
config.ignore_processing_errors = false
config.ignore_download_errors = false
end
CarrierWave のテスト
個別にアップローダーをテストすることは良いことです。テストのスピードを上げるために、テストではプロセスを切り替え、ストレージにはファイルストレージを使うことを推奨します。Rails では下記の記述があるイニシャライザを追加することでそれを行うことができます。
if Rails.env.test? or Rails.env.cucumber?
CarrierWave.configure do |config|
config.storage = :file
config.enable_processing = false
end
end
もしアップローダーに直接 storage :something
をすでに設定している場合はイニシャライザの設定は無視されることを忘れないでください。
プロセスをテストする必要があるときはそれを個別でテストしてください。またプロセスが必要なテストのみでプロセスを有効にしてください。
CarrierWave は便利な RSpec マッチャを持っています。
require 'carrierwave/test/matchers'
describe MyUploader do
include CarrierWave::Test::Matchers
let(:user) { double('user') }
let(:uploader) { MyUploader.new(user, :avatar) }
before do
MyUploader.enable_processing = true
File.open(path_to_file) { |f| uploader.store!(f) }
end
after do
MyUploader.enable_processing = false
uploader.remove!
end
context 'the thumb version' do
it "scales down a landscape image to be exactly 64 by 64 pixels" do
expect(uploader.thumb).to have_dimensions(64, 64)
end
end
context 'the small version' do
it "scales down a landscape image to fit within 200 by 200 pixels" do
expect(uploader.small).to be_no_larger_than(200, 200)
end
end
it "makes the image readable only to the owner and not executable" do
expect(uploader).to have_permissions(0600)
end
it "has the correct format" do
expect(uploader).to be_format('png')
end
end
もしミニテストアサートを探している場合は carrierwave_asserts を確認してください。
アップローダーの enable_processing フラグを設定することによってすべてのバージョンのプロセスも無効になります。
下記のように、特定のバージョンでプロセスフラグを設定することで、単独のバージョンでプロセスを利用可能にすることができます。
@uploader.thumb.enable_processing = true
Fog
fog を使用したい場合は、CarrierWave のイニシャライザに下記の行を追加してください。
config.fog_credentials = { ... } # 特定のクレデンシャルを記述してください。
Amazon S3 の使用
Amazon S3 をサポートするために Fog AWS は使用されます。fog-aws を Gemfile に記載するようにしてください。
gem "fog-aws"
イニシャライザに fog_credentials と fog_directory(S3のバケットのことです) を記載する必要があります。
パフォーマンスのためにディレクトリはすでに作成済みであると仮定されて動作するので、必要な場合はディレクトリを作成してください。
lib/carrierwave/storage/fog.rb に記述されている追加のオプションを渡すこともできます。詳細な例はそこに記載してあります。
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS', # 必須
aws_access_key_id: 'xxx', # IAM Profile を不使用のときは必須
aws_secret_access_key: 'yyy', # IAM Profile を不使用のときは必須
use_iam_profile: true, # オプショナル。デフォルトは false
region: 'eu-west-1', # オプショナル。デフォルトは 'us-east-1'
host: 's3.example.com', # オプショナル。デフォルトは nil
endpoint: 'https://s3.example.com:8080' # オプショナル。デフォルトは nil
}
config.fog_directory = 'name_of_bucket' # 必須
config.fog_public = false # オプショナル。デフォルトは true
config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # オプショナル。デフォルトは {}
end
アップローダーの中ではストレージを :fog に設定してください。
class AvatarUploader < CarrierWave::Uploader::Base
storage :fog
end
CarrierWave::Uploader#url
メソッドを使用して Amazon S3 上のファイルの URL を取得することができます。
注意: Carrierwave が正常に動作するために下記のパーミッションを持っているクレデンシャルが必要です。
s3:ListBucket
s3:PutObject
s3:GetObject
s3:DeleteObject
s3:PutObjectAcl
Rackspace Cloud Files の使用
Fog を利用して Rackspace Cloud Files をサポートすることができます。fog を Gemfile に記載するようにしてください。
gem "fog"
イニシャライザにディレクトリ(コンテナのことです)、ユーザー名、API キーを設定する必要があります。
パフォーマンスのためにディレクトリはすでに作成済みであると仮定されて動作するので、必要な場合はディレクトリを作成してください。
下記は US アカウントを使用した例です。
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'Rackspace',
rackspace_username: 'xxxxxx',
rackspace_api_key: 'yyyyyy',
rackspace_region: :ord # オプショナル。デフォルトは :dfw
}
config.fog_directory = 'name_of_directory'
end
下記は UK アカウントを使用した例です。
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'Rackspace',
rackspace_username: 'xxxxxx',
rackspace_api_key: 'yyyyyy',
rackspace_auth_url: Fog::Rackspace::UK_AUTH_ENDPOINT,
rackspace_region: :lon
}
config.fog_directory = 'name_of_directory'
end
任意で設定に CDNのホスト名を含めることができます。
ホスト名なしではリクエストごとにこの情報を探す必要があるので、この設定を強く推奨します。
config.asset_host = "http://c000000.cdn.rackspacecloud.com"
アップローダーでは :fog をストレージに設定してください。
class AvatarUploader < CarrierWave::Uploader::Base
storage :fog
end
CarrierWave::Uploader#url
メソッドを使用して Rackspace Cloud Files 上のファイルの URL を取得することができます。
Google Storage for Developers の使用
Fog を利用して Google Storage for Developers をサポートすることができます。下記を Gemfile に記載してください。
gem "fog-google"
gem "google-api-client", "> 0.8.5", "< 0.9"
gem "mime-types"
イニシャライザにディレクトリ(バケットのことです)、アクセスキーID、シークレットアクセスキーを設定する必要があります。
パフォーマンスのためにディレクトリはすでに作成済みであると仮定されて動作するので、必要な場合はディレクトリを作成してください。
クレデンシャルの入手方法については fog-google README を読んでください。
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'Google',
google_storage_access_key_id: 'xxxxxx',
google_storage_secret_access_key: 'yyyyyy'
}
config.fog_directory = 'name_of_directory'
end
アップローダーでは :fog をストレージに設定してください。
class AvatarUploader < CarrierWave::Uploader::Base
storage :fog
end
CarrierWave::Uploader#url
メソッドを使用して Google 上のファイルの URL を取得することができます。
Fog の読み込みの最適化
Carrierwave は Fog のどの部分が使用されるかを知らないので、Fog の全ライブラリを読み込もうとします(たとえば [fog-aws
, fog-google
] のように部分的に使用しない限り)。アプリケーションに読み込むクラスを少なくしたいときは、Gemfile で CarrierWave を読み込む前に Fog の使用する部分のライブラリを読み込む必要があります。
gem "fog", "~> 1.27", require: "fog/rackspace/storage"
gem "carrierwave"
バージョンに関していくつか注意点があります:
- この機能は Fog v1.20 から導入されました。
- この機能は CarrierWave v1.0.0 の候補になっています。
もし Gemfile を使用しておらず、どこかで "carrierwave" を require する場合は、carrierwave の前に "fog/rackspace/storage" を require してください。以下は例です。
require "fog/rackspace/storage"
require "carrierwave"
この特別な require は fog gem において切り分けられていない fog プロバイダとともに動作するときにのみ必要となることに気をつけてください。
切り分けられたプロバイダのリストは fog
organizations で見ることができます。
もし疑わしいと思ったのであれば、Fog.constants
を調べて何が読み込まれているかを確認してみてください。
動的なアセットホスト
動的にホストを生成するために asset_host
設定プロパティはプロック(あるいは call
メソッドに応答する何か)に割り当てられます。プロック準拠のオブジェクトはその引数として現在の CarrierWave::Storage::Fog::File
あるいは CarrierWave::SanitizedFile
のインスタンスを取得します。
CarrierWave.configure do |config|
config.asset_host = proc do |file|
identifier = # some logic
"http://#{identifier}.cdn.rackspacecloud.com"
end
end
RMagick の使用
画像をアップロードする場合、いくつかのやり方で画像を処理したくなったり、たとえば画像のサムネイルを作成したくなるかもしれません。CarrierWave は RMagick で画像の処理を簡単にする小さなライブラリを持っており、アップローダーにそれを含めることで使うことができます。
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
end
RMagick は画像を処理する CarrierWave::RMagick#resize_to_fill
のようないくつかのメソッドを提供します。process
コールバックを設定することができ、ファイルがアップロードされるたびにそのメソッドは呼び出されます。
下記に convert のデモがあります。
convert はファイルが同じファイル拡張子を持っているときのみ動作します。つまり filename メソッドを使用することと同じです。
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
process resize_to_fill: [200, 200]
process convert: 'png'
def filename
super.chomp(File.extname(super)) + '.png' if original_filename.present?
end
end
manipulate! メソッドを一致させてみてください。自分で画像処理メソッドを書く良い練習になります。
MiniMagick の使用
MiniMagick は RMagick と似ていますが標準的な ImageMagick キットの一部である 'convert' CLI を使用するすべての操作を実行します。これにより RMagick ライブラリのインストールを気に掛けることなく、ImageMagick を利用できます。
詳細は MiniMagick のサイトをご覧ください。
https://github.com/minimagick/minimagick
ImageMagick コマンドラインオプションの詳細は下記をご覧ください。
http://www.imagemagick.org/script/command-line-options.php
現在、MiniMagick carrierwave プロセッサは RMagick プロセッサとまったく同じメソッドを提供しています。
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process resize_to_fill: [200, 200]
end
Paperclip からの移行
Paperclip を使用している場合は、提供済みの compatibility モジュールを使用することができます。
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::Compatibility::Paperclip
end
詳細は CarrierWave::Compatibility::Paperclip
をご覧ください。
mount_on を使用して正しいカラムを明示するようにしてください。
mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
I18n
Active Record のバリデーションは Rails の i18n
フレームワークを使用しています。下記のキーを翻訳ファイルに追加してください。
errors:
messages:
carrierwave_processing_error: failed to be processed
carrierwave_integrity_error: is not of an allowed file type
carrierwave_download_error: could not be downloaded
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
min_size_error: "File size should be greater than %{min_size}"
max_size_error: "File size should be less than %{max_size}"
carrierwave-i18n
ライブラリは追加の言語設定をサポートしています。
ラージファイル
デフォルトでは、CarrierWave はアップロードファイルを2回コピーします。1回目はキャッシュへのコピー、2回目はストアへのコピーです。サイズが大きいファイルの場合、この処理は多くの時間がかかる可能性があります。
move_to_cache
メソッド、move_to_store
メソッドの片方あるいは両方をオーバーライドすることでこの挙動を変更することができます。
class MyUploader < CarrierWave::Uploader::Base
def move_to_cache
true
end
def move_to_store
true
end
end
move_to_cache
メソッドと move_to_store
メソッドが true を返したとき、ファイルはそれぞれキャッシュとストアへ移動(コピーする代わりに)します。
この機能はローカルファイルシステムストアのみでテストされています。
ActiveRecord コールバックのスキップ
デフォルトでは、アップローダーを ActiveRecord モデルにマウントすることでいくつかのコールバックが追加されます。コード例は下記です。
class User
mount_uploader :avatar, AvatarUploader
end
このコードは下記のコールバックを追加します。
before_save :write_avatar_identifier
after_save :store_previous_changes_for_avatar
after_commit :remove_avatar!, on: :destroy
after_commit :mark_remove_avatar_false, on: :update
after_commit :remove_previously_stored_avatar, on: :update
after_commit :store_avatar!, on: [:create, :update]
任意のコールバックをスキップしたいときは(たとえば新しいファイルをアップロードした後も既存の avatar を残しておきたいとき)、skip_callback
メソッドを使用することができます。
class User
mount_uploader :avatar, AvatarUploader
skip_callback :commit, :after, :remove_previously_stored_avatar
end
Contributing to CarrierWave
See CONTRIBUTING.md
License
Copyright (c) 2008-2015 Jonas Nicklas
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.