我发现了这个问题(在控制台中尝试)。
如果您设置profile = Account::Profile.last 然后调用profile.avatar.attached? 它返回false。这是因为ActiveStorage::Attachment 中的record_type 列设置为User。
因此,您无法访问 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? 来检查头像是否存在。
一个可能更好的解决方案是这样定义实例方法avatar:
def avatar
ActiveStorage::Attached::One.new('avatar', User.find(id), dependent: :purge_later)
end
需要实例化ActiveStorage::Attached::One的对象,但记录必须是User类(匹配record_type),这就是User.find(id)的原因。
现在所有方法都可用:profile.avatar.methods。