未附加文件时的 Rails ActiveStorage 范围

pet*_*ket 6 ruby ruby-on-rails rails-activestorage ruby-on-rails-6

使用 ActiveStorage 时,如何在未附加文件时创建范围。

例如:

class Check < ActiveRecord::Base
  has_one_attached :image
end
Run Code Online (Sandbox Code Playgroud)

我想要类似的东西Check.has_no_attached_image只返回没有现有附加图像的记录。

找到了附加图像但不是相反情况的答案
scope :has_attached_image, -> { joins(image_attachment: :blob) }

Kal*_*san 8

在 Rails 6.1 中,where.missing添加了该功能,结果是:

Check.where.missing(:image_attachment)


Pau*_*eon 6

可以确认missing在 6.1 中确实有效。

这里有一些有用的通用范围,包括许多情况。

不幸的是,没有内置的多个检查导轨,因此单个和多个情况的范围是分开的

  has_one_attached :file
  has_many_attached :documents

  scope :with_attachment, ->(name) { joins(:"#{name}_attachment") }
  scope :with_attachments, ->(name) { joins(:"#{name}_attachments") }
  scope :without_attachment, ->(name) { where.missing(:"#{name}_attachment") }
  scope :without_attachments, ->(name) { where.missing(:"#{name}_attachments") }

  TestModel.with_attachment(:file)
  TestModel.with_attachments(:documents)
  TestModel.without_attachment(:file)
  TestModel.without_attachments(:documents)
Run Code Online (Sandbox Code Playgroud)


Seb*_*lma 3

您可以使用left_joins关联名称 (image + _attachment) 来执行此操作,该名称解释为:

SELECT users.*
FROM users LEFT OUTER JOIN active_storage_attachments
ON active_storage_attachments.record_id = users.id
AND active_storage_attachments.record_type = 'User'
AND active_storage_attachments.name = 'image'
Run Code Online (Sandbox Code Playgroud)

然后应用WHERE过滤器来获取那些与active_storage_attachments表不匹配的用户行:

User.left_joins(:image_attachment).where(active_storage_attachments: { id: nil })
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,查找具有或不具有关联的模型的部分答案 https://solidfoundationwebdev.com/blog/posts/how-to-find-records-based-on-has_many-relationship-being-empty-or-not-in-导轨 (2认同)