我正在尝试使用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
。同样的错误!!!
答案 0 :(得分:0)
看起来c.attachment_file_name
即将出现,而回形针不知道如何处理它。我不确定为什么它是零但是为了绕过它你可以检查它是否是nill并且如果它是跳过它:
if c.attachment_file_name
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
答案 1 :(得分:0)
您是否考虑过修改回形针模型以接受网址作为附件?通过这种方式,您可以将附件移植到新模型,而不是从根本上修改回形针s3存储机制。
将此添加到新模型中:
before_validation :download_remote_attachment, :if => :attachment_url_provided?
...
attr_accessor :attachment_url
private
def attachment_url_provided?
!self.attachment_url.blank?
end
def download_remote_attachment
self.file = do_download_remote_image
end
def do_download_remote_attachment
io = open(attachment_url)
def io.original_filename; base_uri.path.split('/').last; end
io.original_filename.blank? ? nil : io
rescue
end
然后创建一个新的附件对象,将参数:attachment_url传递给它,它将下载它,重新处理它,并将其存储为新模型的附件。唯一的缺点是附件将在S3上存储两次。根据您的应用程序要求,这可能是一件好事
答案 2 :(得分:0)
在黑暗中还有一个远射,来自“为什么它与开发db和非生产db一起工作”的角度。是否有机会attachment
通过has_many :through
关系提供?如果连接表中添加了主键,则可以阅读mySQL可能发生的这种类型的奇怪错误。虽然可以使用sqLite3。所以,一旦你去生产,就会看到错误。只是一个想法。