ruby-on-rails 返回所有关联记录都附加了文件的父记录的范围?

uelo1irk  于 5个月前  发布在  Ruby
关注(0)|答案(1)|浏览(66)

假设有一个UserDocument记录。一个Userhas_many :documents和一个Documentbelongs_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模型编写一个作用域,以返回所有关联的Document记录都附加了file的所有User记录?
示例如下:如果一个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记录的具有附加文件的文档计数。
有什么查询模式对此有用吗?

owfi6suc

owfi6suc1#

我相信你可以在一个单一的查询中做到这一点,但我认为这是有任何文档的用户和有任何文档丢失文件的用户之间的一组差异。我会用3个查询来做到这一点:

  • A:查询所有拥有单据的用户
  • B:查询文档缺少文件的所有用户
  • C:使用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)
  }

字符串
从逻辑上讲,这是三个查询,但从事务上讲,它只有一个。前两个查询直到它们被传递到第三个查询中才被执行,在第三个查询中,它们作为子查询在数据库中执行。

相关问题