如何查询具有 ActiveStorage 附件的记录?
How to query records that have an ActiveStorage attachment?
给定一个带有 ActiveStorage 的模型
class User
has_one_attached :avatar
end
我可以查看单个用户是否有头像
@user.avatar.attached?
但是我如何才能 return 包含所有带(或所有不带)附件的用户的集合?
我尝试使用 joins
来 return 所有有附件的用户,但这似乎对 blob 或附件 table 不起作用,或者我可能没有让语法正确。
我确定我忽略了一些显而易见的事情。是否可以按照以下方式做一些事情:
User.where(attached_avatar: nil)
如果是这样,记录在哪里?
附件关联名称约定
附件关联使用以下约定命名:
<NAME OF ATTACHMENT>_attachment
例如,如果您有 has_one_attached :avatar
,则关联名称将为 avatar_attachment
。
正在查询活动存储附件
现在您知道附件关联是如何命名的,您可以像查询任何其他 Active Record 关联一样使用 joins
查询它们。
例如,给定下面的 User
class
class User
has_one_attached :avatar
end
您可以查询具有该附件的所有User
记录,如下所示
User.joins(:avatar_attachment)
这会执行一个 INNER JOIN
,它只会 return 有附件的记录。
您可以像这样查询所有 User
没有该附件的记录
User.
left_joins(:avatar_attachment).
group(:id).
having("COUNT(active_storage_attachments) = 0")
有点相关,这里是如何对附加记录执行搜索查询:
def self.search_name(search)
with_attached_attachment.
references(:attachment_attachment).
where(ActiveStorage::Blob.arel_table[:filename].matches("%#{search}%"))
end
您只需更新 with_attached_attachment
和 :attachment_attachment
以反映您附加的模型。就我而言,我有 has_one_attached :attachment
对于那些想知道的人,Arel #matches
似乎不容易受到 SQL 注入攻击。
我想知道记录是否有任何附件(我有多个附件,比如 User
的护照和其他文件)所以我可以 display/hide UI 中的一个部分。
根据答案 我已经能够将以下方法添加到 ApplicationRecord
:
def any_attached?
ActiveStorage::Attachment.where(record_type: model_name.to_s, record_id: id).any?
end
然后你可以像这样使用它:
User.last.any_attached?
#=> true
查询带有附件的记录:
User.joins(:avatar_attachment)
不带附件的查询记录:
User.includes(:avatar_attachment).where(avatar_attachment: {id: nil})
给定一个带有 ActiveStorage 的模型
class User
has_one_attached :avatar
end
我可以查看单个用户是否有头像
@user.avatar.attached?
但是我如何才能 return 包含所有带(或所有不带)附件的用户的集合?
我尝试使用 joins
来 return 所有有附件的用户,但这似乎对 blob 或附件 table 不起作用,或者我可能没有让语法正确。
我确定我忽略了一些显而易见的事情。是否可以按照以下方式做一些事情:
User.where(attached_avatar: nil)
如果是这样,记录在哪里?
附件关联名称约定
附件关联使用以下约定命名:
<NAME OF ATTACHMENT>_attachment
例如,如果您有 has_one_attached :avatar
,则关联名称将为 avatar_attachment
。
正在查询活动存储附件
现在您知道附件关联是如何命名的,您可以像查询任何其他 Active Record 关联一样使用 joins
查询它们。
例如,给定下面的 User
class
class User
has_one_attached :avatar
end
您可以查询具有该附件的所有User
记录,如下所示
User.joins(:avatar_attachment)
这会执行一个 INNER JOIN
,它只会 return 有附件的记录。
您可以像这样查询所有 User
没有该附件的记录
User.
left_joins(:avatar_attachment).
group(:id).
having("COUNT(active_storage_attachments) = 0")
有点相关,这里是如何对附加记录执行搜索查询:
def self.search_name(search)
with_attached_attachment.
references(:attachment_attachment).
where(ActiveStorage::Blob.arel_table[:filename].matches("%#{search}%"))
end
您只需更新 with_attached_attachment
和 :attachment_attachment
以反映您附加的模型。就我而言,我有 has_one_attached :attachment
对于那些想知道的人,Arel #matches
似乎不容易受到 SQL 注入攻击。
我想知道记录是否有任何附件(我有多个附件,比如 User
的护照和其他文件)所以我可以 display/hide UI 中的一个部分。
根据答案 ApplicationRecord
:
def any_attached?
ActiveStorage::Attachment.where(record_type: model_name.to_s, record_id: id).any?
end
然后你可以像这样使用它:
User.last.any_attached?
#=> true
查询带有附件的记录:
User.joins(:avatar_attachment)
不带附件的查询记录:
User.includes(:avatar_attachment).where(avatar_attachment: {id: nil})