Ruby
Rails
carrierwave
RubyOnRails

【Rails】CarrierWave・MiniMagickで画像をトリミングできない問題

仮想属性に値が入っていない

Uploaderに以下のようなcropの処理を書いていても、model.crop_xなどの仮想属性の値がnilになるため、cropできないといった問題が起こることがあります。

image_uploader.rb
# (省略)

def crop
  manipulate! do |img|
    crop_x = model.crop_x.to_i
    crop_y = model.crop_y.to_i
    crop_w = model.crop_w.to_i
    crop_h = model.crop_h.to_i
    img.crop "#{crop_w}x#{crop_h}+#{crop_x}+#{crop_y}"
    img = yield(img) if block_given?
    img
  end
end

この場合、コントローラのストロングパラメータで定義しているパラメータの順番が原因の可能性が高いです。
仮想属性より先にimageを定義してしまうと、crop_xなどの仮想属性に値が入っていない状態で、cropしようとするため、エラーとなります。

users_controller.rb
# (省略)

def user_params
  params.require(:user).permit(:name, :email, :image, :crop_x, :crop_y, :crop_w, :crop_h)
end

したがって、以下の様に仮想属性をimageより、先に定義する必要があります。
こうすることで、先に仮想属性がオブジェクトに反映され、正常にcropすることができるはずです。

users_controller.rb
# (省略)

def user_params
  params.require(:user).permit(:name, :email, :crop_x, :crop_y, :crop_w, :crop_h, :image)
end

終わりに

Uploaderの処理が呼ばれる前に仮想属性をモデルオブジェクトに適用させましょう。