开发者

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

开发者 https://www.devze.com 2023-03-25 23:08 出处:网络
I would like to have distinct folders in my S3 bucket to keep the production database clea开发者_运维知识库r from the development environment.

I would like to have distinct folders in my S3 bucket to keep the production database clea开发者_运维知识库r 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


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


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号