Как я могу ссылаться на изображения в конвейере ресурсов из модели? - PullRequest
21 голосов
/ 01 сентября 2011

У меня есть модель с методом для возврата URL-адреса аватара человека, который выглядит следующим образом:

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

Я нахожусь в процессе обновления до 3.1, так что теперь нет необходимости указывать жестко запрограммированное ни одно изображение через конвейер ресурсов. В контроллере или представлении я просто поместил бы его в image_path(), но у меня нет этой опции в модели. Как я могу сгенерировать правильный URL для изображения?

Ответы [ 5 ]

20 голосов
/ 24 октября 2012

Я некоторое время боролся за то, чтобы сделать это правильно, поэтому я решил опубликовать ответ здесь.Хотя вышеприведенное работает для стандартного изображения по умолчанию (т. Е. Одно и то же для каждого стиля скрепки), если вам нужно несколько стилей по умолчанию, вам нужен другой подход.

Если вы хотите, чтобы 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

В этом случае вы все равно можете использовать интерполяцию (: стиль)но придется отключить дактилоскопию / дайджест актива.

Кажется, что все это работает нормально, если вы синхронизируете ресурсы без дайджеста, а также с дайджестом.

8 голосов
/ 01 сентября 2011

Лично я не думаю, что вы действительно должны использовать это значение по умолчанию в модели, так как это детализация. По вашему мнению (хамл):

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

Или создайте своего собственного помощника и используйте его так:

= avatar_or_default(@image)

Когда подобные вещи в рельсах жесткие, это часто признак того, что это не совсем правильно.

6 голосов
/ 20 сентября 2011

Мы решили эту проблему с помощью draper: https://github.com/jcasimir/draper. Draper позволил нам добавить обертку вокруг наших моделей (для использования в представлениях), которые имеют доступ к помощникам.

2 голосов
/ 01 сентября 2011

Скрепка имеет возможность указать URL по умолчанию

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

Вы можете использовать это для показа изображения по умолчанию, если пользователь не загрузил аватар.

1 голос
/ 02 февраля 2019

Использование rails active storage Я решил эту проблему, выполнив следующее:

# 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 %>,

...