paperclip working in development but not working in production? - ruby-on-rails

I'm pretty new to rails and seem to be having an issue with the paperclip gem. I installed the gem and it works well in development (localhost:3000) but when I'm running it on the heroku server, for some reason it does not want to attach files, and the app breaks (error 500 page).
Here is the process i ran... I pushed my file to heroku, heroku ran rake db:migrate (to add paperclip migrations), and then I ran heroku restart (to restart the app with new migrations). This did not seem to help.
Here is the code that I have for paperclip:
user.rb model:
has_attached_file :avatar,
:styles => {:small => "70x70>"},
:url => "/users/:attachment/:id/:style/:basename.:extension",
:path => ":rails_root/public/users/:attachment/:id/:style/:basename.:extension"
validates_attachment_size :avatar, :less_than => 500.kilobytes
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/png']
edit_form.html.haml view:
= form_for (#user || User.new), :html => { :multipart => true } do |f|
...
.profile_picture.text_field
= image_tag current_profile.avatar.url(:small)
%br
= f.file_field :avatar
Again, for some reason it runs great in development, but breaks down in production. Any pointers would be greatly appreciated... I just cant seem to figure this out and it's pretty frustrating. Thank you so much for your time and any help!

In your model.
has_attached_file :picture,
:styles => {:large => "275x450>"},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => "appname/:attachment/:style/:id.:extension"
In s3.yml in your config dir:
development:
bucket: bucketname
access_key_id: key
secret_access_key: key
production:
bucket: bucketname
access_key_id: key
secret_access_key: key
Then go signup for a bucket at Amazon S3: http://aws.amazon.com/s3/

You could be having a few problems. However, the first is that you can not write to the file system on Heroku. You will have to implement a different storage mechanism such as s3. You can read about this limitation here: http://devcenter.heroku.com/articles/read-only-filesystem

Related

AWS::S3::Errors::NoSuchKey No Such Key

I have a Rails 4 app with Paperclip running on Heroku. I recently started encountering a problem that is preventing me from updating any models with attached images. For example, any time I make a change through my site's CMS system to my Company model, the changes are not saved. I've tried changing only the image, the image and various other attributes, and only non-image attributes. It's as if the #company.save is never called in my controller's update action.
I found this issue report and tried the various solutions suggested, but nothing worked.
Here is my Company model:
class Company < ActiveRecord::Base
has_attached_file :logo, :styles => { :medium => "300x300>", :thumb => "100x100>" }
validates_attachment_content_type :logo, :content_type => /\Aimage\/.*\Z/
end
In my logs, I get the following error:
[AWS S3 404 0.022711 0 retries] head_object(:bucket_name=>"myApp",:key=>"companies/profile_photos/000/000/118/original/2015-09-05_19.05.34.jpg") AWS::S3::Errors::NoSuchKey No Such Key
I verified that my S3 credentials are set using heroku config and that they are valid.
I'm not certain, but I suspect that this may have something to do with my recent addition of the following buildpacks:
=== myApp Buildpack URLs
1. https://github.com/bobbus/image-optim-buildpack.git
2. https://github.com/heroku/heroku-buildpack-ruby.git
I've not been able to reproduce the problem on localhost.
Update
I've since opened up an issue report on this problem.
Here is my config.paperclip_defaults block in production.rd
config.paperclip_defaults = {
:storage => :s3,
:s3_protocol => :https,
:s3_host_name => 's3.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']
}
}
Here is my aws.yml:
development:
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
production:
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
Documentation from the GitHub paperclip wiki
Assuming you are using dotenv-rails...
In development.rb and production.rb files:
config.paperclip_defaults = {
storage: :s3,
s3_host_name: ENV['S3_HOST_NAME'],
bucket: ENV['S3_BUCKET_NAME']
}
Make sure to set these variables in your Heroku environment:
$ heroku config:set S3_HOST_NAME=your-s3-hostname-here S3_BUCKET_NAME=your-production-bucket-name-here
Paperclip-with-Amazon-S3
Documentation from rubydoc.info
This states you should have a yaml file with these details specified or write a method on your model.
rubydoc.info Paperclip::Storage::S3
No Such Key is S3's way of saying "404 Not Found."
I don't believe it has any alternate meanings.
The request was authorized and syntactically valid, but there's no file in the bucket at the specified path.
You may want to inspect the contents of your bucket from the AWS console.

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'

Amazon S3 and Spree setup

Cant find a way for S3 to work with spree. There seem to exist few gems for that but dont seem to work for me.
Running rails 3.1.1 with spree 0.70.3.
I am running rails 3.0.10 and spree 0.60 and was able to get spree to use s3 storage over writing to the public folder of the app by doing the following The process should be alike.
add aws-s3 gem to your Gemfile
gem 'aws-s3'
bundle installed and after doing that I created a yaml file in the config directory called s3.yml and it should look something like this.
development: &DEFAULTS
bucket: "YOUR_BUCKET"
access_key_id: "YOUR_ACCESS_KEY"
secret_access_key: "YOUR_ACCESS_SECRET"
test:
<<: *DEFAULTS
bucket: "YOUR_BUCKET"
production:
<<: *DEFAULTS
bucket: "YOUR_BUCKET"
You can specify individual credentials per environment if you like but since mine are all using the same S3 accont I opted to set defaults.
after that you are going to have to override the image model or make a decorator for your which tells paperclip to use S3 and to have it parse the yaml file created for credentials.
the area you want want to override would be this
has_attached_file :attachment,
:styles => {:mini => '48x48>', :small => '200x100>', :product => '240x240>', :large => '600x600>'},
:default_style => :small,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:url => "/assets/products/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
you can change these properties as needed but whats important is that you specify :storage and :s3_credentials.
In the current version of Spree, you can set these values in the admin tools. But if you prefer to maintain it in code but without overriding the Image model, you can set these values in config/initializers/spree.rb. Make sure not to edit them via the admin portal.
S3_CONFIG = YAML.load_file("#{Rails.root}/config/s3.yml")[Rails.env]
Spree.config do |config|
config.attachment_styles = ActiveSupport::JSON.encode({
"mini" => "100x100>",
"small" => "200x200>",
"medium" => "400x600>",
"product" => "400x600>",
"large" => "600x600>",
"xl" => "800x800>",
"xxl" => "1200x1200>",
})
#AWS S3
config.use_s3 = true
config.s3_bucket = S3_CONFIG['bucket']
config.s3_access_key = S3_CONFIG['access_key_id']
config.s3_secret = S3_CONFIG['secret_access_key']
config.attachment_url = 'products/:id/:style/:basename.:extension'
config.attachment_path = 'products/:id/:style/:basename.:extension'
end
You can also try the BitNami Spree AMIs at http://bitnami.org/stack/spree. Regards.

aws s3 paperclip and rails 3.0 error

First off thanks so much for taking the time to read my question. Thank you! It appears that i'm having trouble implementing aws s3 on my webapp. I have a ROR app deployed o heroku and I'd like to allow users to upload a profile picture to their profile.
I've installed imagemagick and paperclip to handle the attachments. Then someone informed me that heroku does not accept uploads and that I'll need to subscribe to aws-s3. That made sense. So I signed up for aws and added the following code to my project:
user.rb (model)
has_attached_file :avatar,
:styles => {:small => "70x70>"},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style/:basename.:extension"
validates_attachment_size :avatar, :less_than => 1.megabytes
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/png']
s3.yml (file is located in config folder) note: all of these buckets exist on my aws-s3
development:
bucket: my_avatar-dev
access_key_id: amazonaccesskey
secret_access_key: amazon_secret_access_key
test:
bucket: myapp_avatar-test
access_key_id: amazonaccesskey
secret_access_key: amazon_secret_access_key
production:
bucket: myapp_avatar-pro
access_key_id: amazonaccesskey
secret_access_key: amazon_secret_access_key
gemfile
gem 'aws-s3'
When I run the application in the development environment (localhost) everything functions properly... I checked AWS and my uploads appear there; however, when I deploy my app to heroku it breaks. To elaborate, the app loads the sign-in screen but as soon as a user signs in, the application breaks and redirects to the error 500 page: "We're sorry, but something went wrong. We've been notified about this issue and we'll take a look at it shortly."
When I hide the following code (and replace :path with some other value) and re-deploy... the app loads, but obviously it lacks the functionality it needs to redirect to aws-s3.
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style/:basename.:extension"
As I mentioned, I'm pretty new to rails... so I'm not sure what I'm doing wrong. Was I supposed to link s3.yml somewhere else, a route or something? Maybe it's something that I need to do while deploying? I'd like to thank anyone who can help me, and I am thankful for your time!

AWS::S3::MissingAccessKey in Paperclip but I've defined both

I'm on Heroku, and this is a portfolio thing which I'm putting up on github for potential employers to look at, so obviously I don't want to stick my keys in a S3.yml file. I've exported S3_KEY and S3_SECRET to my environment both on Heroku and my machine and ruby can access them. But when I try and upload, it gives me the following error:
AWS::S3::MissingAccessKey in Portfolio itemsController#update
You did not provide both required access keys. Please provide the access_key_id and the secret_access_key.
The trace is irrelevant except for my controller line #, which works fine until I try and upload a file. Here's what I have:
class Asset < ActiveRecord::Base
attr_accessible :image, :image_file_name, :image_content_type, :image_file_size, :portfolio_item_id, :order
has_attached_file :image,
:styles => {
:thumb => "100x100#",
:small => "300x300",
:large => "600x600>"
},
:storage => :s3,
:s3_credentials => {
:access_key_id => ENV["S3_KEY"],
:secret_access_key => ENV["S3_SECRET"]
},
:bucket => "bucketybucket",
:path => "portfolio"
end
Anyone know what's going on here? How am I constructing this hash wrong?
Oh, and I've followed this thread, no dice: Paperclip and Amazon S3 Issue
same problem...
seems like that ENV const doesn't load before loading the module. solve by using file argument
like this
:s3_credentials => Rails.root.join('config/amazon_s3.yml')
and in amazon_s3.yml
access_key_id: 'your_key'
secret_access_key: 'your_sec_key'
bucket: 'somebucket'
furthermore, you can set environment variable by using heroku config:add command, which is describe in Heroku DevCenter
The problem is because the Enviroment variable in heroku is different that the enviroment variable in your system, so it may happen that the application works just in one enviroment

Resources