Подтвердить что ты не робот

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

У меня есть модель с методом для возврата 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-адрес изображения?

4b9b3361

Ответ 1

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

Ответ 2

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

Если вы хотите, чтобы 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), но вам придется отключить отпечаток/дайджест активов.

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

Ответ 3

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

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

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

= avatar_or_default(@image)

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

Ответ 4

У Paperclip есть опция указать URL-адрес по умолчанию

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

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

Ответ 5

Используя 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 %>,