在我的Rails应用程序中,我允许用户在创建"发布"时上传图像,它应该直接上传到S3。我在开发和生产中都遇到了以下错误。
编辑:我应该注意,当尝试从表单提交的发布编辑页面上传时会发生此错误。
ArgumentError in ReleasesController#update
missing required :bucket option
Rails.root: /Users/jasondemeuse/pressed
我以前在使用Carrierwave时没有遇到任何问题,但现在我使用Paperclip时,我不知道自己做错了什么。我在SO和其他地方看到的所有修复都是heroku问题,但我在开发中也遇到了同样的问题,这些修复都没有帮助。
以下是相关代码("…"表示不相关的代码段):
开发.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
生产.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
版本.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配置(在.bash_profile中有相同的配置用于开发)
AWS_ACCESS_KEY_ID: XXXXXXXXXXXXXXXX
AWS_BUCKET: appname
AWS_SECRET_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXX
编辑:这是我的控制器的相关部分也是
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
我知道这应该非常简单,我肯定我只是忘记了一些明显的东西,但我一直在复习这个演练以及我找到的修复方法,但似乎什么都不起作用。有没有我忘记运行的rake任务或捆绑包之类的?
提前谢谢!
第2版:下面的答案帮了我很多忙,切换到fog
gem对我来说解决了大多数问题。为了防止其他人遇到同样的问题,我也遇到了另一个问题,这让我很困惑。如果你遇到了heroku问题和Paperclip::PaperclipError (Item model missing required attr_accessor for 'image_file_name'):
,请确保运行heroku rake db:migrate
,然后用heroku restart
重新启动heroku。我加载了我的模式,并错误地认为我不需要这么做。
上面的SO答案可以在这里找到。
我认为这是因为: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文档似乎证实了这一点,即使它的编写/格式化非常糟糕。
编辑:
在我的一个项目中,我使用Paperclip与Fog宝石,这很好地工作
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']
)
在我的案例中,我使用的是foreman(Heroku),它使用.env文件来存储环境变量。所以,当我做rake db:migrate
时,它找不到ENV['AWS_ACCESS_KEY_ID']
我为运行迁移所做的是,我将我的AWS凭据直接临时添加到Carrierwave配置块中,然后在。。。
这不是一个永久的解决方案,因为下次迁移时,它会说同样的话。。。
有关永久解决方案,请参阅:在Rake任务中使用环境变量
它说使用:foreman run rake some_task
通过这种方式,.env中定义的所有变量都被加载到rake
任务中。
将其添加到模块和类内的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