4

私はPaperclipを使用して、Rails3の特定のモデルのアップロードされた画像を管理しています。このモデルは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 

たとえば、メイクChevroletとモデルを作成するとCamaro、画像パスは次のようになります。/cars/chevrolet/camaro/thumb/my_hash.png

Chevroletエントリ名をに変更するとChevy、Railsはで画像を見つけようとしますが、画像の名前が変更/cars/chevy/camaro/thumb/my_hash.pngされていないため、画像が見つかりません。

エントリの名前が変更されたときに、ペーパークリップにすべての画像パスを更新させるにはどうすればよいですか?

ありがとう!

4

2 に答える 2

2

より堅牢なファイルパスでは、makenameの代わりにmakeidを使用できます。つまり/cars/:make_id/:name/:style/:hash.png、メーカー名が変更されても機能し続けます。

于 2012-12-12T07:22:48.490 に答える
0

私はいくつかの方法を見つけました。説明させてください。

まず、この問題は私たちの多くに発生していると思います。デフォルトのペーパークリップ機能にするのは理にかなっています。

2つの解決策があります:

  1. ファイルを新しいロジックに移動/名前変更します:よりクリーンで、CPUの使用量が少なくなり(イメージの再処理なし)、ケースバイケースで(補間、ローカルストレージとS3ストレージなどに応じて)リスクが高くなります(本番サーバーがある場合)。

    人々がファイルを移動することを決めたときの答えは次のとおりです。

  2. 新しいものを作成し、前のものを破棄します。これは私が選んだものです。

したがって、最初に、ファイルロジックが移動しているときにインターセプトする必要があります。私の場合、変更された場合にユーザーのbefore_save :generate_slugを再生成するメソッドがあります。が含まれているslugので、ここにペーパークリップ再生ロジックを配置する必要があります。interpolationslug

私がしなければならなかった唯一のハッキーなことは、ローカルにあるときにファイルへのローカルパスを返すために追加http://localhost:3000することでした。私は本番環境でS3を使用しているので、その場合は機能します。user.avatar.urlURIURI.parse

これが私の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 に答える