ruby-on-railsrubyfogbackblaze

How do I dynamically choose fog provider when interacting with the storage?


I have a simple rails model which contains an image. The images are currently stored at AWS S3, but I need to move them to to Backblaze. I have an uploader class which looks like this too:

class CarImage < ApplicationRecord
  VALID_BACKENDS = [:s3, :backblaze].freeze
  enum backend: VALID_BACKENDS
  mount_uploader :image, CarImageUploader

  belongs_to :car
end

class CarImageUploader < CarrierWave::Uploader::Base
  configure do |config|
    config.fog_credentials = {
      provider: "AWS",
      aws_access_key_id: Rails.application.credentials.aws_access_key_id,
      aws_secret_access_key: Rails.application.credentials.aws_secret_access_key,
      region: Rails.application.credentials.aws_region
    }
    config.fog_directory  = Rails.application.credentials.aws_image_bucket
    config.fog_public     = true
    config.fog_attributes = { "Cache-Control" => "max-age=315576000" }
    config.remove_previously_stored_files_after_update = false
  end

  def store_dir
    "uploads/car_images/#{model.car_id}"
  end
end

Now my problem is, that I need to change the config.fog_credentials dynamically based on the model.backend. How can I achieve this? Can I do it from within one uploader or do I need different uploader classes - and if so, how do I choose which one should be used for the CarImage model based on the backend attribute?

Regards


Solution

  • You can check the backend of the model and set the credentials appropriately:

    class CarImage < ApplicationRecord
      VALID_BACKENDS = [:s3, :backblaze].freeze
      enum backend: VALID_BACKENDS
      mount_uploader :image, CarImageUploader
    
      belongs_to :car
    end
    
    class CarImageUploader < CarrierWave::Uploader::Base
      configure do |config|
        config.fog_public     = true
        config.fog_attributes = { "Cache-Control" => "max-age=315576000" }
        config.remove_previously_stored_files_after_update = false
      end
    
      def fog_credentials
        model.s3? ? s3_fog_credentials : backblaze_fog_credentials
      end
    
      def fog_directory 
        model.s3? ? Rails.application.credentials.aws_image_bucket : Rails.application.credentials.backblaze_image_bucket
      end
    
      def store_dir
        "uploads/car_images/#{model.car_id}"
      end
    
      private
    
      def s3_fog_credentials
        {
          provider: "AWS",
          aws_access_key_id: Rails.application.credentials.aws_access_key_id,
          aws_secret_access_key: Rails.application.credentials.aws_secret_access_key,
          region: Rails.application.credentials.aws_region
        }
      end
    
      def backblaze_fog_credentials
        # your backblaze go here
      end
    end