【问题标题】:Paperclip or Google Cloud Storage issue when renaming paths重命名路径时出现回形针或 Google Cloud Storage 问题
【发布时间】:2016-07-15 14:51:43
【问题描述】:

我有一个带有 Paperclip 的 Rails 应用,并且我使用 Google Cloud Storage。到现在为止还挺好。

为了避免开发和生产使用相同的存储,我决定根据环境将默认的回形针路径更改为另一个。这样每个环境都有自己的目录。然后我不断地将旧图像从默认回形针路径移动到新图像。

问题是现在旧图像给出 404,而我上传的任何新图像都可以正常工作。有什么办法可以解决吗?

这是以前的设置:

module MyApp
  class Application < Rails::Application

  config.paperclip_defaults = {
    storage: :fog,
    fog_public: true,
    fog_directory: 'myapp-01',
    fog_credentials: {
      google_storage_access_key_id: ENV['GOOGLE_STORAGE_ID'],
      google_storage_secret_access_key: ENV['GOOGLE_STORAGE_SECRET'],
      provider: 'Google'
    }
  }
}

我使用以下设置覆盖默认值:

    path: ":rails_env/:class/:attachment/:id_partition/:style/:filename",
    url:  "/:rails_root/:class/:attachment/:id_partition/:style/:filename"

我的猜测是,仅使用新路径更新 Paperclip 配置并将所有图像移动到新目录是不够的。您还需要更新旧记录... 如果您想知道,旧记录指向root/images/?123456789

【问题讨论】:

  • 你给我们看一些代码怎么样?生产/开发设置是什么?您的has_attached_file,就像您复制图像一样,您是否也在同步数据库?如果是这样,怎么做?我也不确定您所说的“旧图像给出 404”是什么意思,您不应该改用新路径吗?
  • 我的猜测是谷歌不让我看到图片。也许一些丢失的权限设置?老实说,url 设置并不能真正起作用,因为在新图像中,src 具有存储桶的默认 Google 网址。

标签: ruby-on-rails paperclip google-cloud-storage image-uploading


【解决方案1】:

你的猜测是正确的。更改配置是不够的,您需要移动文件。这最好留给 rake 任务或后台作业。我有一些 S3 的代码,但它应该让您了解如何为 Google 实现它:

  def old_key(image, file_name_field)
    # Previous `:path`: '/:class/:attachment/:id/:style/:filename'
    klass = self.class.to_s.pluralize.downcase
    attachment = image.pluralize
    "#{klass}/#{attachment}/#{id}/original/#{send(file_name_field)}"
  end

  def re_path(image)
    file_name_field = "#{image}_file_name"
    return if send(file_name_field).blank?

    old_object = bucket.object(old_key(image, file_name_field))
    return unless old_object.exists?

    Rails.logger.warn "Re-saving image attachment #{self.class}/#{id}"
    send "#{image}=", URI.parse(old_object.public_url)
    save
  end

我基本上是在使用自己的插值构建旧路径,在 S3 中找到对象(因此是键/对象术语)并从 S3 重新下载每个图像。请注意这一点,因为如果 Google 允许,您可能会因为下载而不是移动而产生额外费用。

然后我只是在每个对象的每个图像上调用此方法:

Object.each do { |o| o.re_path(:logo); o.re_path(:background); }

【讨论】:

  • 谢谢@Leito,我会按照你的建议执行rake任务,我会告诉你的。
  • 嗨@Leito,我又回到了我暂时搁置的这个问题上。我尝试了这些方法,但我无法完全理解。什么是“桶”?我得到undefined local variable or method 'bucket'
  • 在我的代码中,bucket 是 Aws::S3::Bucket.new 的一个实例,指向正确的存储桶。最终,我有兴趣知道该对象是否存在并获取其 URL。
  • 明白。我正在努力解决这个问题,但这有点矫枉过正。我在 wiki 中看到了 this page 和使用迁移的 this gist,但是很难理解和设置它……太令人沮丧了。希望它不会那么复杂。
  • 就像在 CS 中的任何问题一样,将复杂性抽象出来并变得简单(此时 wiki 文章和我的代码都匹配): (1) 如果 image_file_name 字段为空,则什么也不做; (2) 如果文件不存在*,什么也不做: (3) 读取* 文件内容并通过.image=.save 保存。两者都存在吗?并根据您存储它们的位置读取文件更改。我用的是S3方法,wiki用的是文件系统方法,你需要用谷歌云存储方法。
猜你喜欢
  • 2016-07-06
  • 2014-02-28
  • 2014-09-08
  • 2023-03-12
  • 2012-07-07
  • 2012-12-01
  • 2017-08-27
  • 1970-01-01
  • 2015-01-25
相关资源
最近更新 更多