Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"missing required :bucket option" for Paperclip/S3

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.

like image 694
Jason Avatar asked Jul 25 '13 16:07

Jason


2 Answers

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

like image 60
luigi7up Avatar answered Oct 23 '22 03:10

luigi7up


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']
)
like image 37
Mike Szyndel Avatar answered Oct 23 '22 02:10

Mike Szyndel