在 active_storage_attachments 上设置 record_type 的 ActiveStorage 问题
ActiveStorage issue to set record_type on active_storage_attachments
我对 ActiveStorage 有疑问
情况是我有一个名为 Setting::Profile
的模型和 Admin
table 的名称以及附件 :avatar
上传过程成功,但何时获取图片无法找到,因为在 table active_storage_attachments
属性 record_type
中存储了名称 Setting::Profile
,假设名称为 Admin
如何添加一行为record_type
属性做准备?
谢谢
这是我的演示:https://github.com/SunDi3yansyah-forks/AppActiveStorage
我发现了这个问题(在控制台中尝试)。
如果您设置 profile = Account::Profile.last
然后调用 profile.avatar.attached?
它 returns false。这是因为 ActiveStorage::Attachment
中的列 record_type
设置为用户。
因此,您无法访问 blob,因为 profile.avatar.blob
returns 以下查询:
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
的对象但是record必须是User
class(才能匹配record_type
),所以User.find(id)
.
现在所有方法都可用:profile.avatar.methods
.
我对 ActiveStorage 有疑问
情况是我有一个名为 Setting::Profile
的模型和 Admin
table 的名称以及附件 :avatar
上传过程成功,但何时获取图片无法找到,因为在 table active_storage_attachments
属性 record_type
中存储了名称 Setting::Profile
,假设名称为 Admin
如何添加一行为record_type
属性做准备?
谢谢
这是我的演示:https://github.com/SunDi3yansyah-forks/AppActiveStorage
我发现了这个问题(在控制台中尝试)。
如果您设置 profile = Account::Profile.last
然后调用 profile.avatar.attached?
它 returns false。这是因为 ActiveStorage::Attachment
中的列 record_type
设置为用户。
因此,您无法访问 blob,因为 profile.avatar.blob
returns 以下查询:
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
的对象但是record必须是User
class(才能匹配record_type
),所以User.find(id)
.
现在所有方法都可用:profile.avatar.methods
.