4

我使用 Paperclip 来管理 Rails 3 中某个模型的上传图像。这个模型是belongs_to另一个模型。我希望我的图像路径能够反映这种关系,所以我为此创建了一个自定义插值。

问题是,我还希望能够编辑belongs_to对象的名称,并且我希望 Paperclip 相应地重命名文件。

这是一个简单的例子:

class Make < ActiveRecord:Base
  attr_accessible :name

  has_many :models
end

class Model < ActiveRecord:Base
  attr_accessible :img, :make, :name

  belongs_to :make
  has_attached_file :img, :style => { :thumb => "100x100" },
                    :path => "/cars/:make_name/:name/:style/:hash.png",
                    :hash_secret => "blabla"

  Paperclip.interpolates :make_name do |attachment, style|
    attachment.instance.make.name
  end

  Paperclip.interpolates :name do |attachment, style|
    attachment.instance.name
  end
end 

所以假设我创建了一个 makeChevrolet和一个 Model Camaro,我的图像路径将是/cars/chevrolet/camaro/thumb/my_hash.png

如果我决定将Chevrolet条目名称更改为Chevy,Rails 会尝试将图像定位在/cars/chevy/camaro/thumb/my_hash.png,但由于图像未重命名,因此找不到。

重命名条目时,如何强制 Paperclip 更新所有图像路径?

谢谢!

4

2 回答 2

2

更健壮的文件路径可以使用 make id 而不是 make name。即,/cars/:make_id/:name/:style/:hash.png当品牌名称更改时将继续工作。

于 2012-12-12T07:22:48.490 回答
0

我找到了几种方法。让我解释。

首先,我认为我们中的许多人都遇到过这个问题,将其设为默认回形针功能是有意义的。

有两种解决方案:

  1. 将文件移动/重命名为新逻辑:更干净,使用更少的 CPU(无图像重新处理),但更多的是逐案(取决于插值、本地存储与 S3 存储等)和风险(当有生产服务器时)

    以下是人们决定移动文件时的答案:

  2. 创造一个新的,并摧毁前一个。这是我选择的那个。

因此,首先,您需要在文件逻辑移动时进行拦截。就我而言,我有一个before_save :generate_slug方法可以在slug用户更改时重新生成用户。这是我应该放置回形针再生逻辑的地方,因为我的interpolationcontains slug

我唯一需要做的就是添加http://localhost:3000到,user.avatar.url因为它在本地时返回文件的本地路径,而不是URI用于执行URI.parse. 我在生产中使用 S3,所以在这种情况下它可以工作。

这是我的generate_slug方法:

  def generate_slug
    if !(self.slug == self.fullname.parameterize) # Changed
      if self.avatar.exists? # There actually is an avatar to move
        if self.avatar.url.include? "http"
          avatar_url = self.avatar.url
        else # means url is local path ==> needs to add localhost to have a correct URI
          avatar_url = 'http://localhost:3000' + self.avatar.url
        end
        self.avatar.clear # To remove the former file
      end

      self.slug = self.fullname.parameterize

      if !avatar_url.blank?
        self.avatar = URI.parse(avatar_url)
      end
    end
  end

希望它有帮助,希望有一个更清洁的解决方案!

于 2013-10-30T11:24:15.493 回答