LoginSignup
37
26

More than 3 years have passed since last update.

gem carrierwave の README を翻訳しました

Last updated at Posted at 2020-04-25

概要

gem carrierwave のREADME を翻訳しました。

  • 翻訳について

    • 翻訳サービス DeeplGoole翻訳 の訳文を参考にしている箇所があります。
    • 非公式な翻訳です。
    • 訳文がおかしい箇所があったら指摘をもらえると幸いです。
  • ライセンスについて

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_dirnil として定義してください。

もしプロジェクトルートフォルダの外にファイルを保存するときは、同様の方法で 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.

37
26
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
26