在 Heroku 上移动 Paperclip S3 附件

发布于 2024-11-27 11:20:53 字数 1352 浏览 0 评论 0原文

我正在尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笑忘罢 2024-12-04 11:20:53

看起来 c.attachment_file_name 即将为零,而回形针不知道如何处理它。我不确定为什么它为零,但要解决它,您可以检查它是否为零,如果是则跳过它:

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

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:

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
凉城凉梦凉人心 2024-12-04 11:20:53

您是否考虑过修改回形针模型以接受 URL 作为附件?这样您就可以将附件移植到新模型,而不必从根本上修改回形针 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 上存储两次。根据您的应用程序要求,认为这可能是一件好事

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:

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   

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

油饼 2024-12-04 11:20:53

从“为什么它适用于开发数据库而不适用于生产数据库”的角度,这里还有一个长镜头。是否有机会通过 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 a has_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文