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

时间:2018-09-20 05:23:02

标签: ruby-on-rails rails-activestorage

使用ActiveStorage给出模型

class User 
  has_one_attached :avatar
end

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

@user.avatar.attached? 

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

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

我确定我正在忽略一些明显的问题。是否可以按照以下方式做一些事情?

User.where(attached_avatar: nil)

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

3 个答案:

答案 0 :(得分:7)

附件关联名称公约

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

<NAME OF ATTACHMENT>_attachment

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

查询Active Storage附件

现在您知道附件关联的命名方式,您可以像使用其他任何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")

答案 1 :(得分:1)

略有相关,这是如何对附加的记录执行搜索查询:

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注入攻击。

答案 2 :(得分:1)

我想知道记录中是否有任何附件(我有多个附件,例如护照和Customer #1 IP 1 Customer #1 IP 2 Customer #2 IP 1 Customer #2 IP 2 Customer #2 IP 3 Customer #2 IP 4 dtype: object 的其他文档),所以我可以在UI中显示/隐藏一个部分。

基于答案here,我已经可以向User添加以下方法:

ApplicationRecord

然后您可以像使用它一样

def any_attached?
  ActiveStorage::Attachment.where(record_type: model_name.to_s, record_id: id).any?
end