Я нашел эту проблему (попробуйте в консоли).
Если вы установите profile = Account::Profile.last
, тогда вызовите profile.avatar.attached?
, он вернет false. Это связано с тем, что для столбца record_type
в ActiveStorage::Attachment
установлено значение Пользователь.
Таким образом, вы не можете получить доступ к BLOB-объекту, поскольку profile.avatar.blob
возвращает следующий запрос:
SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = ? AND "active_storage_attachments"."record_type" = ? AND "active_storage_attachments"."name" = ? LIMIT ? [["record_id", 1], ["record_type", "Account::Profile"], ["name", "avatar"], ["LIMIT", 1]]
И ошибка: Module::DelegationError: blob delegated to attachment, but attachment is nil
Один из возможных обходных путей , который я нашел, заключается в определении Account :: Profile следующим образом:
class Account::Profile < ApplicationRecord
self.table_name = "users"
# has_one_attached :avatar # remove this
def avatar
ActiveStorage::Attachment.where(name: :avatar, record_type: 'User', record_id: self.id).last
end
end
Это работает для показа изображения, но имеет проблему, что profile.avatar.class
не ActiveStorage::Attached::One
(например, User.last.avatar.class
), но ActiveStorage::Attachment
.
Таким образом, вы не можете вызвать, например, метод .attached?
для него. Вы должны использовать profile.avatar.present?
, чтобы проверить наличие аватара.
Возможно, лучшее решение состоит в том, чтобы определить аватар метода экземпляра следующим образом:
def avatar
ActiveStorage::Attached::One.new('avatar', User.find(id), dependent: :purge_later)
end
Требуется создать экземпляр объекта ActiveStorage::Attached::One
, но запись должна быть User
class (для соответствия record_type
), поэтому User.find(id)
.
Теперь доступны все методы: profile.avatar.methods
.