如何查询具有ActiveStorage附件的记录?

And*_*vey 8 ruby-on-rails rails-activestorage

给定具有ActiveStorage的模型

class User 
  has_one_attached :avatar
end
Run Code Online (Sandbox Code Playgroud)

我可以检查一个用户是否有化身

@user.avatar.attached? 
Run Code Online (Sandbox Code Playgroud)

但是,如何返回具有附件(或没有附件)的所有用户的集合?

我尝试使用joins返回带有附件的所有Users,但这在blob或附件表上似乎都不起作用,或者我的语法不正确。

我确定我忽略了一些显而易见的事情。是否可以按照以下方式做一些事情:

User.where(attached_avatar: nil)
Run Code Online (Sandbox Code Playgroud)

如果是这样,在哪里记录?

Car*_*III 12

附件关联名称约定

附件关联使用以下约定命名:

<NAME OF ATTACHMENT>_attachment

例如,如果您有,has_one_attached :avatar则关联名称将为avatar_attachment

查询活动存储附件

现在,您知道附件关联的命名方式,您可以joins像使用其他任何Active Record关联一样使用它们来查询它们。

例如,给定User下面的类

class User
   has_one_attached :avatar
end
Run Code Online (Sandbox Code Playgroud)

您可以查询User具有该附件的所有记录,如下所示

User.joins(:avatar_attachment)
Run Code Online (Sandbox Code Playgroud)

这将执行,INNER JOIN该操作将仅返回具有附件的记录。

您可以查询User没有该附件的所有记录,如下所示

User.
  left_joins(:avatar_attachment).
  group(:id).
  having("COUNT(active_storage_attachments) = 0")
Run Code Online (Sandbox Code Playgroud)

  • ...使用我之前评论者提供的纯 ActiveRecord DSL 解决方案:`User.left_joins(:avatar_attachment).where(active_storage_attachments: { id: nil })` (5认同)
  • 最后一个查询的Have子句对我不起作用。相反,我使用了``User.left_joins(:avatar_attachment).where('active_storage_attachments.id为NULL')`'' (4认同)

Jer*_*nch 6

查询记录带附件:

User.joins(:avatar_attachment)
Run Code Online (Sandbox Code Playgroud)

查询不带附件的记录:

User.includes(:avatar_attachment).where(avatar_attachment: {id: nil})
Run Code Online (Sandbox Code Playgroud)


M-D*_*hab 5

我想知道记录是否有任何附件(我有多个附件,比如护照和其他文档User),以便我可以在 UI 中显示/隐藏一个部分。

根据这里的答案我已经能够将以下方法添加到ApplicationRecord

def any_attached?
  ActiveStorage::Attachment.where(record_type: model_name.to_s, record_id: id).any?
end
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

User.last.any_attached?
#=> true
Run Code Online (Sandbox Code Playgroud)