5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Carrierwaveの画像パスをCallbacksで扱う時はafter_commitを使ったほうが良いかも

Last updated at Posted at 2018-01-16

正確に言うと transaction commit後にした方がいいかも、というお話。

Callback時のCarrierwaveの画像パス

Carrierwaveは保存する時に一旦キャッシュディレクトリに画像をキャッシュする作りになっている。デフォルトだとpublic/uploads/tmp/...に入る。

ここで気をつけないといけないのが、after_createやafter_updateのcallback内では、@model.hoge_urlは キャッシュディレクトリのパスを返す。

例えば、Callback時に別のサーバなりに画像のファイルパスを送るようなユースケースの場合、誤ってこのキャッシュのURLが送られてしまうことになり、正式なURLを送ることが出来ない。

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base

  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  storage :fog 

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    base_path = "images/#{model.class.to_s.pluralize.underscore}/#{model.id}"
  end

  ... 
  
end
  
config/initializers/carrierwave.rb
CarrierWave.configure do |config|
  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    region: ENV['AWS_REGION'],
    path_style: true
  }
  config.fog_public = true
  config.fog_directory = ENV['FOG_DIRECTORY']
  config.asset_host = "https://s3-#{ENV['AWS_REGION']}.amazonaws.com/#{ENV['FOG_DIRECTORY']}"
end

app/models/hoge.rb
class Hoge < ApplicationRecord
  mount_uploader :image, ImageUploader
  after_create :send_image

  private

  def send_image
	# POST to Another Applications etc...
	# self.image_url #=> /public/uploads/tmp/... となってしまう
  end
end

どうすれば良いのか

after_commitを使いましょう。

app/models/hoge.rb
class Hoge < ApplicationRecord
  mount_uploader :image, ImageUploader
  after_commit :send_image, on: :create

  private

  def send_image
    # POST to Another Applications etc...
    # self.image_url #=> /public/uploads/tmp/... となってしまう
  end
end

Railsで画像を扱うときにはCarrierwaveを使う人が多いと思うが、思わぬところではまったのでメモ。
トランザクション確定してないくせに別サーバにPOSTしに行くなんてなにを考えて

参考 -StackOverflow

5
4
0

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
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?