如何查询具有 ActiveStorage 附件的记录?
Posted
技术标签:
【中文标题】如何查询具有 ActiveStorage 附件的记录?【英文标题】:How to query records that have an ActiveStorage attachment? 【发布时间】:2019-02-24 08:26:29 【问题描述】:给定一个带有 ActiveStorage 的模型
class User
has_one_attached :avatar
end
我可以检查单个用户是否有头像
@user.avatar.attached?
但是如何返回包含(或不包含)附件的所有用户的集合?
我尝试使用 joins
返回所有带有附件的用户,但这似乎不适用于 blob 或附件表,或者我的语法可能不正确。
我确定我忽略了一些明显的东西。是否可以按照以下方式做一些事情:
User.where(attached_avatar: nil)
如果是这样,记录在哪里?
【问题讨论】:
【参考方案1】:附件关联名称约定
附件关联使用以下约定命名:
<NAME OF ATTACHMENT>_attachment
例如,如果您有has_one_attached :avatar
,则关联名称将为avatar_attachment
。
查询活动存储附件
现在您知道附件关联是如何命名的,您可以像使用任何其他 Active Record 关联一样使用 joins
查询它们。
例如,给定下面的User
类
class User
has_one_attached :avatar
end
您可以查询所有具有该附件的User
记录,如下所示
User.joins(:avatar_attachment)
这会执行INNER JOIN
,它只会返回带有附件的记录。
您可以像这样查询所有没有该附件的User
记录
User.
left_joins(:avatar_attachment).
group(:id).
having("COUNT(active_storage_attachments) = 0")
【讨论】:
最后一个查询的 having 子句对我不起作用。相反,我使用了User.left_joins(:avatar_attachment).where('active_storage_attachments.id is NULL')
... 使用来自我之前的评论者的解决方案的纯 ActiveRecord DSL:User.left_joins(:avatar_attachment).where(active_storage_attachments: id: nil )
多张图片是.left_joins(:avatars_attachments)
(头像上是复数,附件上是和)【参考方案2】:
有点相关,这里是如何对附加记录执行搜索查询:
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 注入攻击。
【讨论】:
【参考方案3】:我想知道一条记录是否有任何附件(我有多个附件,比如护照和 User
的其他文档),以便我可以在 UI 中显示/隐藏一个部分。
基于答案here 我已经能够将以下方法添加到ApplicationRecord
:
def any_attached?
ActiveStorage::Attachment.where(record_type: model_name.to_s, record_id: id).any?
end
然后你可以像这样使用它:
User.last.any_attached?
#=> true
【讨论】:
以上是关于如何查询具有 ActiveStorage 附件的记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Amazon S3 中自定义 Rails 5.2 ActiveStorage 附件的路径?
Rails 5.2 的 ActiveStorage 图像上传错误:signed_id 委托给附件,但附件为零
上传前的 Rails 5.2 ActiveStorage 裁剪附件