Ответ 1
Мы решили эту проблему с помощью draper: https://github.com/jcasimir/draper. Draper позволяет нам добавить обертку вокруг наших моделей (для использования в представлениях), которые имеют доступ к помощникам.
У меня есть модель с методом для возврата 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-адрес изображения?
Мы решили эту проблему с помощью draper: https://github.com/jcasimir/draper. Draper позволяет нам добавить обертку вокруг наших моделей (для использования в представлениях), которые имеют доступ к помощникам.
Я боролся с тем, чтобы получить это право на некоторое время, поэтому я думал, что отправлю ответ здесь. Хотя приведенное выше работает для стандартного изображения по умолчанию (т.е. Одного для каждого стиля скрепки), если вам нужны несколько стилей по умолчанию, вам нужен другой подход.
Если вы хотите, чтобы 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), но вам придется отключить отпечаток/дайджест активов.
Все это работает нормально, если вы синхронизируете активы без дайджеста, а также с дайджестом.
Лично я не думаю, что вы действительно должны ставить этот дефолт в модели, так как это детализация. В вашем (haml) представлении:
= image_tag(@image.avatar_url || 'none.png')
Или создайте своего помощника и используйте его так:
= avatar_or_default(@image)
Когда такие вещи сложны в рельсах, это часто признак того, что это не совсем правильно.
У Paperclip есть опция указать URL-адрес по умолчанию
has_attached_file :avatar, :default_url => '/images/.../missing_:style.png'
Вы можете использовать это для отображения изображения по умолчанию 'в случае, если пользователь не загрузил аватар.
Используя 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 %>
,