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 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.
精彩评论