Delayed Paperclip with s3 Missing Bucket Option in Production - ruby-on-rails

I'm trying to used delayed_paperclip to process image resize in the background. This process works in development but in production I get this in my delayed job's last error.
missing required :bucket option\n/home/server_username/project_folder_name/shared/bundle/ruby/2.2.0/gems/paperclip-4.3.0/lib/paperclip/storage/s3.rb:218:in 'bucket_name'...etc
In application.rb
config.paperclip_defaults = {
:storage => :s3,
:url =>':s3_domain_url',
:s3_protocol => 'https',
:path => '/:class/:attachment/:id_partition/:style/:filename',
:bucket => ENV['s3_bucket_name'],
:s3_credentials => {
:access_key_id => ENV['s3_id'],
:secret_access_key => ENV['s3_key']
}
}
In my class file
has_attached_file :uploaded_file,
:styles => { original: "990x990#",large: "300x300#", medium: "200x200#", thumb: "100x100#"},
only_process: [:medium]
process_in_background :uploaded_file, queue: "queue_name",
only_process: [:original, :large, :thumb]
Uploading to s3 works without using delayed_paperclip. I just wanted to use this library so people didn't have to wait for these to be uploaded/resiszed. I'm working on Ubuntu14.04. Deploying w/ Capistrano.
I saw a couple places that the bucket should be outside of the s3_credentials, so I moved it to where it is now. So I've tried it there and inside s3_credentials -- no change either way.
The medium image is uploaded and resized immediately and works.
Let me know if there is some info I didn't provide.

Related

Rails Paperclip adds extra folder pointing to Cloudfront (between :url and :path)

I'm having trouble with loading images uploaded to s3 via my cloudfront distribution. I can get it to work fine loading straight from s3, but not from cloudfront.
I have set the config.action_controller.asset_host to my distribution url and have set up paperclip
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => 's3-sa-east-1.amazonaws.com',
:url => ':asset_host',
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
with the appropriate code in the model :path =>
':class/:id/:style/:class:style:id.:extension'
and every time I upload a file and try to access it i get
https://XXXXXX.cloudfront.net/images/:class/:id/:style/:class:style:id.:extension
I honestly can't figure out where the /images/ is coming from that is added between the url and the path. And I would be very greatful for any help or tips to solve this!
Thanks

Paperclip + AWS S3, Prefixing remote path with my local path

I'm using Paperclip with a Rails 4 app and Amazon S3 storage. On my development machine, the site is running at
/Users/Jeff/Sites/example.com/web
When I upload a file with Paperclip to S3, the remote path in S3 inherits my local folder structure.
http://s3.amazonaws.com/example_com_bucket/Users/Jeff/Sites/example.com/web/public/assets/uploads/my_class/8/medium/some_image.png?1383060287
Why is this happening? How do I strip that part out? I tried changing the :path property but that only seemed to affect the "application" part of the path (e.g. after /assets/uploads) My site is still in development, so I don't care about having to preserve links.
My config is...
config.paperclip_defaults = {
:storage => :s3,
:path => '/:class/:attachment/:id_partition/:style/:filename',
:s3_credentials => {
:bucket => 'example_com_bucket',
:access_key_id => '...',
:secret_access_key => '...'
}
}
I had this exact same issue when I was using the :url parameter where I should have been using the :path parameter:
has_attached_file :primary_photo,
:styles => ...,
:storage => :s3,
:s3_host_name => 's3-us-west-2.amazonaws.com',
:s3_credentials => 'config/s3.yml',
:url => '/product/:attachment/:id/:style/:filename'
I fixed it by changing my config to this:
has_attached_file :primary_photo,
:styles => ...,
:storage => :s3,
:s3_host_name => 's3-us-west-2.amazonaws.com',
:s3_credentials => 'config/s3.yml',
:path => '/product/:attachment/:id/:style/:filename'

Paperclip on heroku with S3 - not working

I am using paperclip to handle image uploads in my Rails app. All works fine running in the development environment locally using the File Storage.
Now I am trying to get this working using S3 (because the app is to run on Heroku). I have set up a bucket and set the appropriate parameters in development.rb and production.rb as per the instructions here: https://devcenter.heroku.com/articles/paperclip-s3
When I start the server, I get the following error:
/Users/ganzogo/.rvm/gems/ruby-1.9.3-p362/gems/railties-3.2.13/lib/rails/railtie/configuration.rb:85:in `method_missing': undefined method `paperclip' for #<Rails::Application::Configuration:0x007fcb8b952000> (NoMethodError)
from /Users/ganzogo/Documents/acknowledgement/true-rails/config/environments/development.rb:41:in `block in <top (required)>'
And then it crashes.
The line referred to in the error is:
config.paperclip.defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
I get exactly the same error if I try to run on Heroku. Has anyone been through this and have any idea what I have missed?
It looks like you may have a typo in your configuration block. Try changing config.paperclip.defaults = {...} to config.paperclip_defaults = {...} and that should solve your problem.
We got this working on one of our live apps
The difference is you need to put the credentials into the model itself. Here's what we've got:
#app/models/image.rb
#Image Upload
Paperclip.options[:command_path] = 'C:\RailsInstaller\ImageMagick'
has_attached_file :image,
:styles => { :medium => "x300", :thumb => "x100" },
:default_url => "*******",
:storage => :s3,
:bucket => '******',
:s3_credentials => S3_CREDENTIALS
#app/config/application.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => 's3-eu-west-1.amazonaws.com'
}
In Heroku, you'll need to add the various environment variables to your config settings

Rails 4, Paperclip, Amazon S3 Config Amazon Path

I'm trying to configure the endpoint which is returned from paperclip when my object is successfully uploaded to Amazon's S3 service. The upload and everything is working correctly, but the URL that is being returned is incorrect for displaying the upload.
Right now, the url that is being returned is http://s3.amazonaws.com/path/to/my/items (as seen in the picture below).
Instead of s3.amazonaws.com, I would like the root to be specific to the bucket's location (e.g. s3-us-west-1.amazonaws.com/path/to/my/items)
Where should I try and configure a different url path (from s3.amazonaws.com to something else)? I've tried to add a url with the above path into my configuration file like:
#Paperclip Amazon S3
config.paperclip_defaults = {
:storage => :s3,
:url => "https://s3-us-west-1.amazonaws.com/",
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
Which did not appear to have any effect. Please advise on where I should be setting this option!
Thanks in advance!
If you're going to use S3, we've found that you have to include the S3 credentials in your actual model (not just the config files). Here's what we do:
Model
#Image Upload
Paperclip.options[:command_path] = 'C:\RailsInstaller\ImageMagick'
has_attached_file :image,
:styles => { :medium => "x300", :thumb => "x100" },
:default_url => "****",
:storage => :s3,
:bucket => '****',
:s3_credentials => S3_CREDENTIALS,
:url => "/:image/:id/:style/:basename.:extension",
:path => ":image/:id/:style/:basename.:extension"
config/application.rb
# Paperclip (for Amazon) (we use EU servers)
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => 's3-eu-west-1.amazonaws.com'
}
config/s3.yml
#Amazon AWS Config
development:
access_key_id: **********
secret_access_key: **************
bucket: ****
production:
access_key_id: ***********
secret_access_key: ***********
bucket: ****
Hope this helps?
I also had the same problem when migrating to Spree 2.2 and am still not sure how to solve it the correct way. It seems like Paperclip should have been updating the path from the configuration, but it isn't.
Lacking a better solution, I've overridden the Spree::Image class like this:
1 Spree::Image.class_eval do
2 has_attached_file :attachment,
3 styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>' },
4 default_style: :product,
5 url: '/spree/products/:id/:style/:basename.:extension',
6 path: 'products/:id/:style/:basename.:extension',
7 convert_options: { all: '-strip -auto-orient -colorspace sRGB' }ยท
8 end
After some experimentation I have found that setting :s3_host_name globally suffices. I ended up with the same problem because I was setting :s3_region, which was being used by Paperclip (post-4.3.1, with aws-sdk 2) for storing attachments, but not when generating the URLs.
This may also be of interest to readers who end up on this problem: https://github.com/thoughtbot/paperclip/wiki/Restricting-Access-to-Objects-Stored-on-Amazon-S3

Getting S3 Credentials from the database at startup in rails

Using a combination of the rails-settings gem and paperclip, I've got my application set up such that one can specify S3 credentials in the database (through an interface in the front end) and can then declare attachments like this;
class Asset < ActiveRecord::Base
has_attached_file :attachment,
:default_url => "content/no-img.jpg",
:s3_credentials => {
:access_key_id => Settings.AWS_ACCESS_KEY_ID,
:secret_access_key => Settings.AWS_SECRET_ACCESS_KEY
}
This works great, but this isn't the only type of attachment in the application (there are other things such as client logos). I'm finding that I need to specify the S3 credentials on every one. I've already tucked some of the defaults away in my app config file;
class Application < Rails::Application
#Paperclip Defaults
config.paperclip_defaults =
{
:storage => :s3,
:bucket => "my-bucket-name"
}
And this all works great, but if I try to pull down the username and password into the app config too, I get the following error;
ActiveRecord::ConnectionNotEstablished (ActiveRecord::ConnectionNotEstablished)
A fairly self explanatory error message, but how do I get around it? If I put the config in the environment files I get the same issue, and if I put them in an initializer like this;
#Paperclip Defaults
MyApp::Application.config.paperclip_defaults =
{
:storage => :s3,
:bucket => "my-bucket-name",
:s3_credentials => {
:access_key_id => RailsSettings::Settings.AWS_ACCESS_KEY_ID,
:secret_access_key => RailsSettings::Settings.AWS_SECRET_ACCESS_KEY
}
}
Then the values don't seem to get picked up and paperclip defaults back to storing the files in my local system directory. Could anyone advise on the best approach to handling this?
EDIT
So after re-reading the documentation I discovered "After Initializers", which gets around the whole active-record not being loaded issue. I have this in my app config;
config.after_initialize do
#Paperclip Defaults
config.paperclip_defaults =
{
:storage => :s3,
:bucket => "my-bucket-name",
:s3_credentials => {
:access_key_id => RailsSettings::Settings.AWS_ACCESS_KEY_ID,
:secret_access_key => RailsSettings::Settings.AWS_SECRET_ACCESS_KEY
}
}
end
And specify this in each model;
has_attached_file :attachment,
:default_url => "content/no-img.jpg",
:path => "#{Rails.env}/:client_name/#{DateTime.now.year}/:name/:basename/:basename-:style.:extension"
yet it still isn't picking up the defaults I specify (it still tries to put them in the public/system folder)
Right, sorted. If anyone has this issue, here's the solution (you basically need to use the "initializers" method to switch active record on before you set the config);
initializer "active_record.initialize_database" do |app|
app.config.paperclip_defaults =
{
:storage => :s3,
:bucket => "my-bucket-name",
:s3_credentials => {
:access_key_id => RailsSettings::Settings.AWS_ACCESS_KEY_ID,
:secret_access_key => RailsSettings::Settings.AWS_SECRET_ACCESS_KEY
}
}
end

Resources