使用ActiveStorage时,如何在未附加文件时创建作用域。
例如:
class Check < ActiveRecord::Base
has_one_attached :image
end
我希望像Check.has_no_attached_image
这样的东西只返回没有现有附加图像的记录。
找到了附加图像但不是相反情况的答案scope :has_attached_image, -> { joins(image_attachment: :blob) }
在Rails 6.1中,添加了where.missing
功能,结果是:
Check.where.missing(:image_attachment)
可以确认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)
您可以使用具有关联名称(图像+_attachment
(的left_joins
来执行此操作,该名称被解释为:
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'
然后应用WHERE
过滤器来获得那些与active_storage_attachments
表不匹配的用户行:
User.left_joins(:image_attachment).where(active_storage_attachments: { id: nil })
我只是想添加到这个答案中,因为上面的答案对我不起作用(可能是因为我使用的是Rails 6?不确定(。以下是对我有效的方法:
scope :without_attached_image, -> { left_joins(:image_attachment).where('active_storage_attachments.id IS NULL') }