Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
771 views
in Technique[技术] by (71.8m points)

amazon s3 - How can I set paperclip's storage mechanism based on the current Rails environment?

I have a rails application that has multiple models with paperclip attachments that are all uploaded to S3. This app also has a large test suite that is run quite often. The downside with this is that a ton of files are uploaded to our S3 account on every test run, making the test suite run slowly. It also slows down development a bit, and requires you to have an internet connection in order to work on the code.

Is there a reasonable way to set the paperclip storage mechanism based on the Rails environment? Ideally, our test and development environments would use the local filesystem storage, and the production environment would use S3 storage.

I'd also like to extract this logic into a shared module of some kind, since we have several models that will need this behavior. I'd like to avoid a solution like this inside of every model:

### We don't want to do this in our models...
if Rails.env.production?
  has_attached_file :image, :styles => {...},
                    :path => "images/:uuid_partition/:uuid/:style.:extension",
                    :storage => :s3,
                    :url => ':s3_authenticated_url', # generates an expiring url
                    :s3_credentials => File.join(Rails.root, 'config', 's3.yml'),
                    :s3_permissions => 'private',
                    :s3_protocol => 'https'
else
  has_attached_file :image, :styles => {...},
                    :storage => :filesystem
                    # Default :path and :url should be used for dev/test envs.
end

Update: The sticky part is that the attachment's :path and :url options need to differ depending on which storage system is being used.

Any advice or suggestions would be greatly appreciated! :-)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I like Barry's suggestion better and there's nothing keeping you from setting the variable to a hash, that can then be merged with the paperclip options.

In config/environments/development.rb and test.rb set something like

PAPERCLIP_STORAGE_OPTIONS = {}

And in config/environments/production.rb

PAPERCLIP_STORAGE_OPTIONS = {:storage => :s3, 
                               :s3_credentials => "#{Rails.root}/config/s3.yml",
                               :path => "/:style/:filename"}

Finally in your paperclip model:

has_attached_file :image, {
    :styles => {:thumb => '50x50#', :original => '800x800>'}
}.merge(PAPERCLIP_STORAGE_OPTIONS)

Update: A similar approach was recently implemented in Paperclip for Rails 3.x apps. Environment specific settings can now be set with config.paperclip_defaults = {:storage => :s3, ...}.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...