carrierwaveuploader / carrierwave

Classier solution for file uploads for Rails, Sinatra and other Ruby web frameworks
https://github.com/carrierwaveuploader/carrierwave
8.78k stars 1.66k forks source link

Conditional processing of versions behaves oddly #2720

Closed clickworkorange closed 2 weeks ago

clickworkorange commented 8 months ago

I have a model Image which has a role:string attribute and mounts :image_file uploader. I want to check the role attribute in my ImageFileUploader class, and produce a different set of versions depending on its value:

  version :thumb do
    # always produce this
    process resize_to_fit: [240, 240]
  end

  version :normal, if: :not_banner? do
    # only produce this if role != "banner"
    process resize_to_fit: [1200, 1200]
  end

  version :banner, if: :is_banner? do
    # only produce this if role == "banner"
    process resize_to_fill: [1200, 600]
  end

  def not_banner?(image)
    model.role != "banner"
  end

  def is_banner?(image)
    model.role == "banner"
  end

If I upload an image and set the role to "banner" only the :thumb gets created. For any other role the :normal version is produced and the :banner version is skipped - just as expected. Why doesn't the :is_banner? condition work here?

mshibuya commented 2 weeks ago

Most likely cause for this is assignment order. Suppose your controller receives the params like this:

{image: {image_file: #<File ...>, role: "thumb", ...}}

CarrierWave processing happens on the assignment of image_file, without waiting for the assignment of role. Please make sure that role is set to correct value, before assigning the file.