In my Rails app I'm letting users upload an image when they create a "release", and it should upload directly to S3. I'm getting the following error in both development and production.
EDIT: I should note that this error happens when trying to upload from the release edit page on form submit.
ArgumentError in ReleasesController#update
missing required :bucket option
Rails.root: /Users/jasondemeuse/pressed
I've done this before with no issues using Carrierwave, but can't figure out what I'm doing wrong now that I'm using Paperclip. All of the fixes I've seen on SO and elsewhere are heroku issues, but I'm getting the same problem on development and none of the fixes have helped.
Here's the relevant code ("..." indicates not relevant snippets):
development.rb
Appname::Application.configure do
...
config.paperclip_defaults = {
:storage => :s3,
:s3_protocol => 'http',
:s3_credentials => {
:bucket => ENV['AWS_BUCKET'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
end
production.rb
Appname::Application.configure do
...
config.paperclip_defaults = {
:storage => :s3,
:s3_protocol => 'http',
:s3_credentials => {
:bucket => ENV['AWS_BUCKET'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
end
release.rb
class Release < ActiveRecord::Base
attr_accessible ... :banner
belongs_to :user
has_attached_file :banner, styles: {
thumb: '100x100>',
square: '200x200#',
medium: '300x300>',
spread: '1200x200'
}
has_many :banners, :dependent => :destroy
accepts_nested_attributes_for :banners, :allow_destroy => true
end
show.html.erb
<%= image_tag @release.banner.url(:medium) %>
<%= @release.banner.url %>
// Have both of these in for now to see if they work, but since the upload isn't working it's giving me the missing.png
_form.html.erb
<%= f.label "Add A Banner?" %><br />
<%= f.file_field :banner %>
heroku config (have the same in .bash_profile for development)
AWS_ACCESS_KEY_ID: XXXXXXXXXXXXXXXX
AWS_BUCKET: appname
AWS_SECRET_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXX
EDIT: Here's my the relevant part of my controller too
def update
@release = Release.find(params[:id])
respond_to do |format|
if @release.update_attributes(params[:release])
format.html { redirect_to [@user,@release], notice: 'Release was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @release.errors, status: :unprocessable_entity }
end
end
end
I know this should be extremely simple and I'm sure I just forgot something obvious, but I've been going over this walkthrough as well as fixes I've found and nothing seems to work. Is there a rake task or bundle that I forgot to run or something?
Thank you in advance!
EDIT 2: The below answers helped me out a lot, and switching to the fog
gem fixed most things for me. Just in case others are having these same issues, I also was having another problem that was making this one confusing for me. If you're having heroku issues and a Paperclip::PaperclipError (Item model missing required attr_accessor for 'image_file_name'):
, make sure you run heroku rake db:migrate
then restart heroku with heroku restart
. I loaded my schema and wrongly assumed I wouldn't need to do that.
A SO answer with the above can be found here.
In my case it was that I was using foreman (Heroku) which uses an .env file to store environment variables. So, when I did rake db:migrate
it couldn't find the ENV['AWS_ACCESS_KEY_ID']
What I did to run my migration was I temporarily added my AWS credentials directlñy into Carrierwave config block and then removed them after...
This is not a permanent solution because next time you migrate it will say the same thing...
For the permanent solution see: Use environment variables in Rake task
which says use: foreman run rake some_task
this way all variables defined in .env are loaded for the rake
task too
I think that's because :bucket
should be an option passed to Paperclip not to S3.
Fixed config
config.paperclip_defaults = {
:storage => :s3,
:s3_protocol => 'http',
:bucket => ENV['AWS_BUCKET'],
:s3_credentials => {
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
And Paperclip::Storage::S3 doc seems to confirm that, even being so poorly written/formatted.
EDIT:
In one of my projects I use Paperclip with Fog gem and this works well
Paperclip::Attachment.default_options.merge!(
:storage => :fog,
:fog_credentials => {
:provider => 'AWS',
:aws_access_key_id => ENV['S3_ACCESS_KEY_ID'],
:aws_secret_access_key => ENV['S3_SECRET_ACCESS_KEY'],
:region => 'eu-west-1' # in case you need it
},
:fog_directory => ENV['S3_BUCKET'], # only one of those is needed but I don't remember which
:bucket => ENV['S3_BUCKET']
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With