在 Heroku 上移动 Paperclip S3 附件
我正在尝试使用 Heroku、Paperclip 和 S3 做一些非常简单的事情 - 将一个模型的附件设置为等于另一个模型的附件。
这是我整理的自定义 rake 任务:
task :migrate => :environment do
@companies = Company.where("attachment_file_name IS NOT NULL")
@companies.each do |c|
if c.attachments.where("attachment_file_name = ?", c.attachment_file_name).blank?
# i.e. if there are no instances of Attachment that match c.attachment
a = Attachment.new( :company_id => c.id, :name => "Default" )
a.attachment = c.attachment
a.save
end
end
end
因此,我尝试将 Company.attachment 移动到新 Attachment 模型的新实例。在我的本地开发服务器上,它运行得很好。
一旦推送到 Heroku,我收到以下错误,指向行 a.attachment = c.attachment
。
The specified key does not exist.
我为一家在 Heroku 控制台中有附件的公司手动尝试该操作,然后得到:
TypeError: can't convert nil into String
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/storage/s3.rb:131:in `extname'
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/storage/s3.rb:131:in `to_file'
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/attachment.rb:81:in `assign'
/app/vendor/plugins/paperclip/lib/paperclip.rb:245:in `attachment='
你知道这里发生了什么吗?
我刚刚尝试了c.attachment = c.attachment
。同样的错误!!!
I'm trying to do something very simple using Heroku, Paperclip and S3 - set one model's attachment to equal another's.
Here's a custom rake task I put together:
task :migrate => :environment do
@companies = Company.where("attachment_file_name IS NOT NULL")
@companies.each do |c|
if c.attachments.where("attachment_file_name = ?", c.attachment_file_name).blank?
# i.e. if there are no instances of Attachment that match c.attachment
a = Attachment.new( :company_id => c.id, :name => "Default" )
a.attachment = c.attachment
a.save
end
end
end
So, I'm trying to move Company.attachment to a new instance of the new Attachment model. On my local development server, it works beautifully.
Once pushed to Heroku, I'm getting the following error pointing to the line a.attachment = c.attachment
.
The specified key does not exist.
I try the operation manually for a company that has an attachment in the heroku console and I get:
TypeError: can't convert nil into String
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/storage/s3.rb:131:in `extname'
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/storage/s3.rb:131:in `to_file'
/app/.bundle/gems/ruby/1.8/gems/paperclip-2.3.6/lib/paperclip/attachment.rb:81:in `assign'
/app/vendor/plugins/paperclip/lib/paperclip.rb:245:in `attachment='
Do you know what's going on here?
I just tried c.attachment = c.attachment
. Same error!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来
c.attachment_file_name
即将为零,而回形针不知道如何处理它。我不确定为什么它为零,但要解决它,您可以检查它是否为零,如果是则跳过它:Looks like
c.attachment_file_name
is coming up nil and paperclip doesn't know what to do with it. I'm not sure why it's nil but to get around it you can just check to see if it's nill and skip it if it is:您是否考虑过修改回形针模型以接受 URL 作为附件?这样您就可以将附件移植到新模型,而不必从根本上修改回形针 s3 存储机制。
将其添加到您的新模型中:
...
然后要创建一个新的附件对象,请将参数 :attachment_url 传递给它,它将下载它,重新处理它,并将其存储为新模型的附件。唯一的缺点是附件将在 S3 上存储两次。根据您的应用程序要求,认为这可能是一件好事
Have you considered modifying your paperclip model to accept a URL as an attachment? That way you can port over your attachements to a new model and not radically modify the paperclip s3 storage mechansim.
Add this to your new model:
...
Then to create a new attachment object, pass it the parameter :attachment_url and it will download it, re-process it, and store it as an attachment for the new model. The only downside to this is that the attachment will be stored twice on S3. Depending on your app requirements thought that might be a good thing
从“为什么它适用于开发数据库而不适用于生产数据库”的角度,这里还有一个长镜头。是否有机会通过
has_many :through
关系提供附件
?已经读过,如果连接表添加了主键,则 mySQL 可能会发生这种类型的奇怪错误。不过可以与 sqLite3 一起使用。因此,一旦投入生产,就会看到错误。只是一个想法。One more long shot in the dark here, from the "why does it work with development db and not production db" angle. Any chance
attachment
is made available via ahas_many :through
relationship? Have read this type of bizarre error can occur with mySQL if the join table has a primary key added to it. Will work with sqLite3 though. So, once you go to production, the error is seen. Just a thought.