Paperclip and S3 storage seed - ruby-on-rails

I've setup my Rails 4 app to use S3 storage over Paperclip gem. Upload of files is working perfectly through create method, images are show using = image_tag(#listing.avatar.url)...
The problem I have is when I use seed_dump and create the seed.db; reset the database and seed the data again the paths to S3 where the images are not correct anymore?!
application.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['FOG_DIRECTORY'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
listing.rb
has_attached_file :avatar
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
Long story short: how do you dump your data and seed it back again without losing the avatar URL?

Related

Delayed Paperclip with s3 Missing Bucket Option in Production

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.

Paperclip, S3, Heroku: Missing Image

Long time viewer, first time asker. I've searched for this topic but don't believe I've found the answer.
I have a Post model that has an image. I'm using the Paperclip gem, saving to Amazon S3, and hosting on Heroku.
The file upload form works fine, because I can see that images are sent to my S3 bucket.
The issue is that, the images don't actually show in production.
Here's my model:
class Post < ActiveRecord::Base
attr_accessor :image_file_name, :image_content_type, :image_file_size, :image_updated_at
belongs_to :user
has_many :reviews
has_attached_file :image, styles: { medium: "700x500#", small: "350x250>" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
And here's my config/production.rb:
# Required for Paperclip / AWS
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']
}
}
And here's my show.html.haml file:
.clearfix
.post_image_description
= image_tag #post.image.url(:medium)
.description= simple_format(#post.address)
.description= simple_format(#post.description)
Shouldn't the #post.image.url be enough? What may I be missing to properly route to the image?
This is what I see when I pull Heroku Logs:
2015-06-23T15:38:26.181383+00:00 app[web.1]: ActionController::RoutingError (No route matches [GET] "/images/medium/missing.png"):
For reference, here's my repository for the project: https://github.com/lucasvocos/pitstop
Please let me know if there is anything else to provide in the question, too. As this is my first time asking. Thanks everyone.
I had a similar problem that the upload was working but the display was showing a broken link. I checked the source for the link and it was not pointing to the url shown for the image on S3. I had to add the host name to my paperclip config
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => 's3-us-west-2.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']
}
}
You need to set heroku environment variable for s3 bucket variable:
heroku config:set S3_BUCKET_NAME='Your Bucket Name'
heroku config:set AWS_ACCESS_KEY_ID='Your AWS ID'
heroku config:set AWS_SECRET_ACCESS_KEY='Your AWS Secrete Key'
You have to commit the missing.png in \public\images\medium.(make sure \public\images\medium\missing.png exist, then commit). This images is the default until you upload some valid image.
However, also is recommended to define the url in model, something like this:
has_attached_file :image, styles: {
medium: "700x500#",
small: "350x250>" }, :url => '/:class/:attachment/:id/:style_:basename.:extension'

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

Rails, PaperClip, S3, Heroku: Model icon fields not being saved

I am using Rails 3.2 + Heroku + S3 + Paperclip to store an icon on my User model. The model is not saving the 4 icon fields though. The images are getting processed and saved on S3 correctly and no errors are occurring. I also have another model that has a document being stored via Paperclip and S3. That model works perfectly in all cases. The User icon works locally but not on Heroku.
production.rb relevant configuration
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['AWS_BUCKET'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
User model code:
class User < ActiveRecord::Base
attr_accessible :icon
has_attached_file :icon, :url => "/system/:rails_env/:attachment/:style/:hash.:extension",
:hash_data => ":class/:attachment/:id",
:hash_secret => "superSecretThing",
:styles => { :medium => "300x300>", :thumb => "100x100>" },
:default_url => "/blank.png"
...
Controller code: (This code is kind of crazy because I am AJAXing files Base64 encoded.)
params[:user][:icon_data]
decoded_file = Base64.decode64(data)
begin
split_name = params[:user][:icon_file_name].split(".")
file = Tempfile.new([split_name[0..-2].join("."), ".#{split_name[-1]}"])
file.binmode
file.write(decoded_file)
file.close
#user.icon = open(file)
#user.icon_file_name = params[:user][:icon_file_name]
ensure
file.unlink
end
#user.save
I do an almost identical process on another model with a Paperclip attachment and it works flawlessly. In both cases the attachment is being saved correctly to S3 and no errors are being raised. This gist has example output for a controller action from the Heroku logs.
I am pretty baffled because the other model works fine. The only real difference is that the User attachment does image processing but that part appears to be working fine.
The problem is the same as this one, but the solution there does not apply.
Thoughts?
So the problem is that not including the :path argument makes it try to use the :url parameter for both the url and the path. The real fix is to include the :path parameter in addition to the url.
So for example a fixed configuration that works both locally and on Heroku:
has_attached_file :icon,
:url => "/system/:rails_env/:attachment/:style/:hash.:extension",
:path => "public/system/:rails_env/:attachment/:style/:hash.:extension",
:hash_data => ":class/:attachment/:id",
:hash_secret => "superDuperSecret",
:styles => { :medium => "300x300>", :thumb => "100x100>" },
:default_url => "/blank.png"

Resources