ruby-on-railsrubycarrierwave

How do you pass additional variables to a CarrierWave uploader in Rails?


I see this has been asked a few times over the years (eg Upload path based on a record value for Carrier wave Direct, Passing a parameter to the uploader / accessing a model's attribute from within the uploader / letting the user pick the thumbnail size), but I'm convinced I must be overcomplicating this, as it seems like a very simple problem...

I have a very straightforward Video model that mounts an uploader:

class Video < ApplicationRecord
  mount_uploader :file, VideoUploader
end

In the controller, I allow two parameters:

    def video_params
      params.require(:video).permit(:title, :file)
    end

In the actual VideoUploader, I seem to have access to a number of variables derived from the :file column using class builtins (eg original_filename), and I can process the file using ffmpeg parameters. However, I want the parameters to be conditional based on the :title string, and I have no idea how to scope it or access it. What is the absolute simplest way to make sure this variable is accessible to those methods?

Edit: here's the uploader code:

class VideoUploader < CarrierWave::Uploader::Base

  require 'streamio-ffmpeg'
  include CarrierWave::Video
  case @title # not working
  when "tblend_glitch"
    process encode_video: [:mp4,
      resolution: "1280x960",
      custom: %w(-to 5 -vf scale=-2:720,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference,spp=4:10,tblend=all_mode=average,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference,spp=4:10,tblend=all_mode=average,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference,spp=4:10,tblend=all_mode=average,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference)]
...
  end
  def full_filename(for_file)
    super.chomp(File.extname(super)) + '.mp4'
  end
  def filename
    original_filename.chomp(File.extname(original_filename)) + '.mp4'
  end
  storage :file
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end

Thanks!


Solution

  • You should be able to access the instance in the uploader using the model method.

    You haven't defined @title — it's nil. You can create a conditional version with the following code.

    class VideoUploader < CarrierWave::Uploader::Base
      version :tblend, if: :tblend_glitch? do # use a better version name
        process encode_video: [:mp4,
          resolution: "1280x960",
          custom: %w(-to 5 -vf scale=-2:720,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference,spp=4:10,tblend=all_mode=average,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference,spp=4:10,tblend=all_mode=average,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference,spp=4:10,tblend=all_mode=average,tblend=all_mode=difference,tblend=all_mode=difference,tblend=all_mode=difference)]
      end
    
       # rest of the code
    
      private
    
      def tblend_glitch?
        model.title == 'tblend_glitch'
      end
    end
    

    Ref: https://github.com/carrierwaveuploader/carrierwave#conditional-versions