PEF
PEF

Reputation: 973

Configure Environment to Use Different Storage Paths on Amazon S3 with Carrierwave

I would like to have distinct folders in my S3 bucket to keep the production database clear from the development environment. I am not sure how to do this, here is the skeleton I've come up with in the carrierwave initializer:

if Rails.env.test? or Rails.env.development?
   CarrierWave.configure do |config|
     //configure dev storage path
   end
end

if Rails.production?
   CarrierWave.configure do |config|
     //configure prod storage path
   end
end

Upvotes: 8

Views: 4886

Answers (3)

danielricecodes
danielricecodes

Reputation: 3586

Consider the following initializer:

#config/initializers/carrierwave.rb

CarrierWave.configure do |config|
  config.enable_processing = true

  # For testing, upload files to local `tmp` folder.
  if Rails.env.test?
    config.storage = :file
    config.root = "#{Rails.root}/tmp/"
  elsif Rails.env.development?
    config.storage = :file
    config.root = "#{Rails.root}/public/"
  else #staging, production
    config.fog_credentials = {
      :provider              => 'AWS',
      :aws_access_key_id     => ENV['S3_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET']
    }
    config.cache_dir = "#{Rails.root}/tmp/uploads" # To let CarrierWave work on heroku
    config.fog_directory    = ENV['S3_BUCKET']
    config.fog_public     = false
    config.storage = :fog
  end
end
  • In development, the uploads are sent to the local public directory.
  • In test mode, to the Rails tmp directory.
  • And finally, in "else" environment (which is usually a production or staging environment) we direct the files to S3 using Environmental Variables to determine which bucket and AWS credentials to use.

Upvotes: 3

Simon Peck
Simon Peck

Reputation: 517

Use different Amazon s3 buckets for your different environments. In your various environment .rb files, set the environment specific asset_host. Then you can avoid detecting the Rails environment in your uploader.

For example, in production.rb:

config.action_controller.asset_host = "production_bucket_name.s3.amazonaws.com"

The asset_host in development.rb becomes:

config.action_controller.asset_host = "development_bucket_name.s3.amazonaws.com"

etc.

(Also consider using a CDN instead of hosting directly from S3).

Then your uploader becomes:

class ImageUploader < CarrierWave::Uploader::Base

  ...

  # Override the directory where uploaded files will be stored.
  def store_dir
    "uploads/images/#{model.id}"
  end

  ...

end

This is a better technique from the standpoint of replicating production in your various other environments.

Upvotes: 0

iwasrobbed
iwasrobbed

Reputation: 46703

Two options:

Option1: You don't care about organizing the files by model ID

In your carrierwave.rb initializer:

Rails.env.production? ? (primary_folder = "production") : (primary_folder = "test")

CarrierWave.configure do |config|
  # stores in either "production/..." or "test/..." folders
  config.store_dir = "#{primary_folder}/uploads/images"
end

Option 2: You DO care about organizing the files by model ID (i.e. user ID)

In your uploader file (i.e. image_uploader.rb within the uploaders directory):

class ImageUploader < CarrierWave::Uploader::Base

  ...

  # Override the directory where uploaded files will be stored.
  def store_dir
    Rails.env.production? ? (primary_folder = "production") : (primary_folder = "test")

    # stores in either "production/..." or "test/..." folders
    "#{primary_folder}/uploads/images/#{model.id}"
  end

  ...

end

Upvotes: 5

Related Questions