carrierwaveuploader / carrierwave

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

Conditional 'process convert: :format' always changes file extension #2723

Open langalex opened 5 months ago

langalex commented 5 months ago

Given an uploader:

class MyUploader < CarrierWave::Uploader::Base
  process convert: :webp, if: :should_convert_to_webp?

  def should_convert_to_webp?(filename)
    ..
  end
end

The file extension is always changed to webp, even if should_convert_to_webp? returns false.

The error was introduced in 3.0.5:

module CarrierWave
  module Uploader
    module Processing
        def process(*args)
          new_processors = args.inject({}) do |hash, arg|
            arg = { arg => [] } unless arg.is_a?(Hash)
            hash.merge!(arg)
          end

          condition_type = new_processors.keys.detect { |key| [:if, :unless].include?(key) }
          condition = new_processors.delete(:if) || new_processors.delete(:unless)
          new_processors.each do |processor, processor_args|
            self.processors += [[processor, processor_args, condition, condition_type]]

            if processor == :convert
              # Treat :convert specially, since it should trigger the file extension change
              force_extension processor_args
            end
          end
        end
      end # ClassMethods
    end
  end
end

The if processor == :convert clause runs on the class level, ignoring the condition which is evaluated on the instance level, when an actual file is uploaded.