環境
- Rails 5.2.2
- CarrierWave 1.3.1
- 2019/11時点の最新は
2.0.2
ですが、Backgrounderを使うために、1.x台の最新としています。
- 2019/11時点の最新は
- CarrierWave Backgrounder 0.4.2
注意
CarrierWave Backgrounderのインストールについて
githubを指定することで、最新の0.4.2
(且つ、後述のbugを修正したもの)をインストール出来ます。
Gemfile
gem 'carrierwave_backgrounder', github: 'leoduquesnel/carrierwave_backgrounder'
Gemfile.lock
GIT
remote: git://github.com/leoduquesnel/carrierwave_backgrounder.git
revision: 128b22a4c8de0db762ca5f005225c87a944c93e1
specs:
carrierwave_backgrounder (0.4.2)
carrierwave (>= 0.5, < 2.0)
mime-types (~> 2.99)
- バージョンを指定せずに、
CarrierWave Backgrounder
をインストールすると、0.0.2
がインストールされます。この場合、後述のrails g carrierwave_backgrounder:install
でエラーが出ます。 - このページを参考にして、リポジトリを指定してインストールしましたが、アップロード時に以下のエラーが出ます。
gem "carrierwave_backgrounder", github: 'lardawge/carrierwave_backgrounder'
NoMethodError - undefined method `cache_name' for #<CarrierWave::Mounter:0x00007f9a5dc77488>
- 最終的に、このページを参考にして、前述のリポジトリを使いました。
手順
前提
以下のgemのインストールは済んでいること
- carrierwave
- carrierwave_backgrounder(※インストール方法は、上記参照)
- sidekiq(ActiveJobで利用)
CarrierWaveの設定
carrierwaveのgeneratorを使って、対象となるクラスを作成
rails generate uploader Image
# -> app/uploaders/image_uploader.rb にファイルが作成される。
対象のテーブルにカラムを追加する
今回はproducts
テーブルにimage:string
を追加する
rails g migration add_image_to_products image:string
class AddImageToProducts < ActiveRecord::Migration[5.2]
def change
add_column :products, :image, :string
end
end
対象クラスにuploaderを定義する
app/models/product.rb
mount_uploader :image, ImageUploader
uploaderでmove_to_cache
、move_to_store
を有効にする(任意?)。
app/uploaders/image_uploader.rb
def move_to_cache
true
end
def move_to_store
true
end
controllerのparamsにimage
を追加する(割愛)
CarrierWave Backgrounderの設定
対象クラスにbackground処理の設定を行う
app/models/product.rb
process_in_background :image # こちらは任意かも
store_in_background :image
対象テーブルに必要なカラムを追加する
rails g migration add_image_processing_to_products image_processing:boolean
class AddImageProcessingToProducts < ActiveRecord::Migration[5.2]
def change
add_column :products, :image_processing, :boolean
end
end
rails g migration add_image_tmp_to_products image_tmp:string
class AddImageTmpToProducts < ActiveRecord::Migration[5.2]
def change
add_column :products, :image_tmp, :string
end
end
uploaderにバックグラウンド処理を定義する
app/uploaders/image_uploader.rb
include ::CarrierWave::Backgrounder::Delay
initializersの生成
rails g carrierwave_backgrounder:install
# -> config/initializers/carrierwave_backgrounder.rb が生成される
active_job
を使うように変更する。
config/initializers/carrierwave_backgrounder.rb
CarrierWave::Backgrounder.configure do |c|
# c.backend :delayed_job, queue: :carrierwave
c.backend :active_job, queue: :carrierwave
# c.backend :resque, queue: :carrierwave
# c.backend :sidekiq, queue: :carrierwave
# c.backend :girl_friday, queue: :carrierwave
# c.backend :sucker_punch, queue: :carrierwave
# c.backend :qu, queue: :carrierwave
# c.backend :qc
end
バックグラウンド処理をするための設定を追加
app/models/product.rb
store_in_background :image, UploadImageJob
app/models/product.rb
# 最終的には、以下のような形になっている
mount_uploader :image, ImageUploader
process_in_background :image
store_in_background :image, UploadImageJob
バックグラウンドジョブの設定
app/jobs/upload_image_job.rb
class UploadDigitalImageJob < ApplicationJob
# include ::CarrierWave::Workers::ProcessAssetMixin
include ::CarrierWave::Workers::StoreAssetMixin
include RescueFromError
queue_as :carrierwave
after_perform do
# 処理完了後に、メールを送信する
image = job.record
UserMailer.notification_uploaded(image).deliver_later
end
end