问题描述
我在 this 上阅读了 How to query records that have an ActiveStorage attachment? 有用的答案
我正在尝试查询所有拥有至少一张图片的用户(易于调整相关问题,见下文),和的第一张图片是 {{1 }}
目前我所知道的
.variable?
但我不知道如何只返回第一张图片为 User.
left_joins(:images_attachments).
group(:id).
having("COUNT(active_storage_attachments) > 0")
的用户(即图片大小改变时不会出错的用户)
解决方法
由于 variable?
是在 ActiveStorage::Blob::Representable
模块中定义的,因此您应该加载每个 ActiveStorage::Blob
对象并检查调用该方法时返回的值是什么。但我认为这可以作为最后的选择。
知道 variable?
方法的作用只是检查 blob content_type
是否是 ActiveStorage.variable_content_types
中预定义的对象之一,您可以尝试这样做,但使用 SQL:
User.left_joins(:main_image_attachment)
.joins('INNER JOIN active_storage_blobs ON active_storage_blobs.id = active_storage_attachments.blob_id')
.group(:id)
.having('COUNT(active_storage_attachments.id) > 0')
.where(active_storage_blobs: { content_type: ActiveStorage.variable_content_types })
因此,您执行的操作几乎相同,但只需将 active_storage_blobs
表放入内存以访问 content_type
列。
我正在尝试查询至少有一张图片(易于调整相关问题,见下文)且第一张图片是 .variable 的所有用户?
你想要 Users who have at least one image
,所以 INNER JOIN
应该没问题。
如果你想要 whose first image
字面意思,这可以通过 join subquery
来实现。
结合@SebastianPalma 的回答,我们可以这样做:
# Query for attachments with just first image of users
subquery = ActiveStorage::Attachment.where(record_type: 'User')
.order(:record_id,created_at: :asc)
.select('DISTINCT ON (record_id) *')
.to_sql
User.joins("INNER JOIN (#{subquery}) AS active_storage_attachments ON active_storage_attachments.id = users.id")
.joins('INNER JOIN active_storage_blobs ON active_storage_blobs.id = active_storage_attachments.blob_id')
.where(active_storage_blobs: { content_type: ActiveStorage.variable_content_types })