【问题标题】:Moving Paperclip S3 attachments on Heroku在 Heroku 上移动 Paperclip S3 附件
【发布时间】:2011-08-02 21:40:17
【问题描述】:

我正在尝试使用 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。同样的错误!!!

【问题讨论】:

  • 在黑暗中拍摄,但您是否尝试过使用read_attribute 来读取c.attachment 属性...比如a.attachment = c.read_attribute(:attachment)?我之前不得不使用 CarrierWave 来获取图像属性,因为他们在幕后做了一些奇怪的事情,所以它可能与 PaperClip 的方式相同
  • @iWasRobbed - 我刚刚在 Heroku 控制台中尝试过,但它返回了 nil 值。
  • 你找到解决办法了吗?
  • 我知道它不应该,但是 c.attachment.errors 包含什么有趣的东西吗? rdoc.info/github/thoughtbot/paperclip/master/Paperclip/…

标签: ruby-on-rails ruby-on-rails-3 amazon-s3 heroku paperclip


【解决方案1】:

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

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

【讨论】:

  • 感谢您的想法。我已经检查过 file_name 是否存在。事实上,在我的手动工作中,我确保文件在那里并且准备好了。还有其他原因导致此问题。
【解决方案2】:

您是否考虑过修改回形针模型以接受 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 上存储两次。根据您的应用要求认为这可能是一件好事

【讨论】:

    【解决方案3】:

    从“为什么它适用于开发数据库而不是生产数据库”的角度来看,这里又是一个在黑暗中的远景。 attachment 是否有机会通过has_many :through 关系获得?如果连接表添加了主键,mySQL 可能会发生这种类型的奇怪错误。不过可以与 sqLite3 一起使用。因此,一旦您投入生产,就会看到错误。只是一个想法。

    【讨论】:

      猜你喜欢
      • 2012-02-22
      • 2012-09-23
      • 2019-07-14
      • 2012-05-02
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      相关资源
      最近更新 更多