返回父记录的范围,其中所有关联记录都附加有文件?

问题描述 投票:0回答:1

假设有

User
Document
记录。一个
User
has_many :documents
和一个
Document
belongs_to
一个
User

一个

Document
记录
has_one_attached :file
.

我已经有两个

Document
范围,它们将返回带或不带附加文件的记录:

文档.rb

  scope :without_attached_file, -> { where.missing(:file_blob) }
  scope :with_attached_file, -> { where.associated(:file_blob) }

如何为

User
模型编写一个范围,以返回所有关联的
User
记录都附加了
Document
的所有
file
记录?

示例:如果

User
有 10 个关联的
Document
记录,并且所有 10 个记录都有一个附加的
file
,则范围应包括该
User
记录。

我相信我应该首先

count
关联的
Document
记录的数量,然后将该数字与
user.documents.with_attached_file.count
返回的数字进行比较,但我无法理解它。

我想出了类似的东西:

   scope :with_attached_files_for_all_documents, -> {
    joins(documents: :file_attachment)
      .group('users.id')
      .having("COUNT(documents.id) = COUNT(CASE WHEN active_storage_attachments.record_type = 'Document' THEN documents.id ELSE NULL END)")
  }

但这只是返回每个给定

User
记录具有附加文件的文档计数。

有对此有用的查询模式吗?

ruby-on-rails postgresql scope
1个回答
0
投票

我确信您可以在单个查询中完成此操作,但我认为这是拥有任何文档的用户与拥有任何缺少文件的文档的用户之间的一组差异。我会通过 3 个查询来完成此操作:

  • A:查询拥有文档的所有用户
  • B:查询所有文档缺失文件的用户
  • C:使用 A 和 B 作为子查询来查询 A 和 B 之间的集合差异

然后你可以像这样构建你的范围:

  scope :with_attached_files_for_all_documents, -> {
    users_with_files = Document.with_attached_files.select(:user_id)
    users_missing_files = Document.without_attached_files.select(:user_id)
    where(id: users_with_files).where.not(id: users_missing_files)
  }

逻辑上,这是三个查询,但事务上只有一个。前两个在传递到第三个之前不会执行,它们在数据库中作为子查询执行。

© www.soinside.com 2019 - 2024. All rights reserved.