11

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.

4

3 回答 3

19

我认为那是因为:bucket应该是传递给 Paperclip 而不是 S3 的选项。
固定配置

  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']
    }
  }

Paperclip::Storage::S3 doc 似乎证实了这一点,即使写得如此糟糕/格式化。

编辑:

在我的一个项目中,我将 Paperclip 与 Fog gem 一起使用,效果很好

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']
)
于 2013-07-30T14:43:07.723 回答
1

就我而言,我使用的是工头(Heroku),它使用.env文件来存储环境变量。所以,当我这样做时,rake db:migrate它找不到ENV['AWS_ACCESS_KEY_ID']

我为运行迁移所做的只是暂时将我的 AWS 凭证直接添加到 Carrierwave 配置块中,然后在...之后将其删除。

这不是一个永久的解决方案,因为下次迁移时它会说同样的话......

有关永久解决方案,请参阅:在 Rake 任务中使用环境变量

其中说 use:foreman run rake some_task这样所有在 .env 中定义的变量也被加载用于rake任务

于 2014-07-05T23:17:03.510 回答
0

将此添加到模块和类中的 application.rb 文件中。创建一个local_env.yml文件并将您的环境变量放在那里。此代码将在服务器启动时加载您的环境变量:

config.autoload_paths += %W(#{config.root}/lib)
config.before_configuration do
    env_file = File.join(Rails.root, 'config', 'local_env.yml')
    YAML.load(File.open(env_file)).each do |key, value|
        ENV[key.to_s] = value
    end if File.exists?(env_file)
end
于 2016-03-16T01:20:59.623 回答