web-dev-qa-db-ja.com

モデルからアセットパイプラインの画像を参照するにはどうすればよいですか?

次のようなURLを人のアバターに返すメソッドを持つモデルがあります。

_ def avatar_url
   if self.avatar?
     self.avatar.url # This uses Paperclip
   else
     "/images/avatars/none.png"
   end
 end
_

3.1にアップグレードしている最中なので、ハードコードされたnoneイメージをアセットパイプラインから参照する必要があります。コントローラーまたはビューでは、それをimage_path()でラップするだけですが、モデルにはそのオプションがありません。画像への正しいURLを生成するにはどうすればよいですか?

22
Michael Fairley

Draperを使用してこの問題を解決しました: https://github.com/jcasimir/draper 。 Draperを使用すると、ヘルパーにアクセスできるモデル(ビューで使用するため)のラッパーを追加できます。

6
Michael Fairley

私はしばらくこれを正しくするのに苦労したので、ここに答えを投稿しようと思いました。上記は標準のデフォルト画像(つまり、ペーパークリップスタイルごとに同じ画像)で機能しますが、複数のデフォルトスタイルが必要な場合は、異なるアプローチが必要です。

デフォルトのURLをアセットパイプラインとアセットの同期で適切に再生し、スタイルごとに異なるデフォルトの画像が必要な場合は、フィンガープリントなしでアセットパスを生成する必要があります。そうしないと、AssetNotPrecompiledエラーが多数発生します。

そのようです:

   :default_url => ActionController::Base.helpers.asset_path("/missing/:style.png", :digest => false)

またはペーパークリップオプション:

   :default_url => lambda { |a| "#{a.instance.create_default_url}" }

次に、ペーパークリップが添付されているモデルのインスタンスメソッド:

def create_default_url
   ActionController::Base.helpers.asset_path("/missing/:style.png", :digest => false)
end

この場合でも、補間(:style)を使用できますが、アセットのフィンガープリント/ダイジェストをオフにする必要があります。

ダイジェストなしのアセットとダイジェストありのアセットを同期している限り、これはすべて正常に機能しているようです。

20
Iain

個人的には、ビューの詳細であるため、このデフォルトをモデルに実際に配置する必要はないと思います。あなたの(haml)ビューで:

= image_tag(@image.avatar_url || 'none.png')

または、独自のヘルパーを作成して、次のように使用します。

= avatar_or_default(@image)

このようなことがRailsで難しい場合、それはしばしばそれが正確に正しくないことの兆候です。

9
Peter

ペーパークリップには、デフォルトのURLを指定するオプションがあります

has_attached_file :avatar, :default_url => '/images/.../missing_:style.png'

ユーザーがアバターをアップロードしていない場合は、これを使用してデフォルトの画像を提供できます。

2
socjopata

Railsアクティブストレージを使用して、これを行うことでこの問題を解決しました:

# Post.rb
def Post < ApplicationRecord
    has_one_attached :image

    def thumbnail
        self.image.attached? ? self.image.variant(resize: "150x150").processed.service_url : 'placeholder.png';
    end

    def medium
        self.image.attached? ? self.image.variant(resize: "300x300").processed.service_url : 'placeholder.png';
    end

    def large
        self.image.attached? ? self.image.variant(resize: "600x600").processed.service_url : 'placeholder.png';
    end
end

次に、あなたの見解では、単に電話してください:<%= image_tag @post.thumbnail %>

1
Brad