如何在 rails 中查找有关联模型记录或没有关联模型记录的模型记录?
How to find model records having some or no associated model records in rails?
我正在使用 Rails7 创建员工管理系统应用程序。这里我有一个 Employee 模型,一个包含所有文档列表的 Document 模型,这两个模型通过具有 Employee ID 和 Document ID 的 EmployeeDocuments 模型相关联。现在我想使用一个动作邮件发送一份员工列表,其中包含他们尚未提交的文件。问题是我无法在单个查询中提交一些或没有提交文件的员工列表。
我可以得到没有提交文件的员工,如下所示:
Employee.includes(:documents).where(documents: {id: nil})
和员工提交的部分或全部文件:
Employee.includes(:documents).where.not(documents: {id: nil})
我想要这个列表,这样我就可以通过以下方式遍历他们丢失的文档:
Document.where.not(id: employee.documents.pluck(:id))
并发送列表。
目前,我的邮件看起来像这样:
class DocsNotifierMailer < ApplicationMailer
default from: 'user@email.com'
def notification_email
@employees = Employee.all
mail(to: 'recipient@email.com',
subject: 'Reminder for missing documents')
end
end
所以我可以在我的 HTML 模板中获取所有员工的列表,并且我正在使用这样的 If 语句:
<% if employee.documents.length < Document.all.count %>
过滤掉所有文档的员工。
但我想在邮件本身中过滤它们。
由于我是初学者,因此找不到解决方法。请帮忙。
Rails 7 内置了这个
Employee.where.associated(:documents)
我认为以下内容可能适合您:
Employee
.left_outer_joins(:documents)
.group('employees.id')
.having("COUNT(documents.id) < #{Document.count}")
这些问题非常令人困惑,但是如果您有一个文档列表并且想要找到与所有或部分记录匹配的员工,您可以通过分组并使用必须在组上设置条件来实现:
Employee
.left_joins(:documents)
.where(documents: { id: documents })
.group(:id)
# HAVING COUNT("documents"."id") < 7
.having(Document.arel_table[:id].count.lt(documents.size))
这会给那些没有匹配所有文档但可能有一些的用户。可以使用 eq
、lteq
、gt
或 gteq
代替 lt
(小于)来简单地更改条件。
在 Postgres 上,您可以使用 COUNT(documents.*)
代替:
.having(Document.arel_table[Arel.star].count.lt(documents.size))
我正在使用 Rails7 创建员工管理系统应用程序。这里我有一个 Employee 模型,一个包含所有文档列表的 Document 模型,这两个模型通过具有 Employee ID 和 Document ID 的 EmployeeDocuments 模型相关联。现在我想使用一个动作邮件发送一份员工列表,其中包含他们尚未提交的文件。问题是我无法在单个查询中提交一些或没有提交文件的员工列表。 我可以得到没有提交文件的员工,如下所示:
Employee.includes(:documents).where(documents: {id: nil})
和员工提交的部分或全部文件:
Employee.includes(:documents).where.not(documents: {id: nil})
我想要这个列表,这样我就可以通过以下方式遍历他们丢失的文档:
Document.where.not(id: employee.documents.pluck(:id))
并发送列表。 目前,我的邮件看起来像这样:
class DocsNotifierMailer < ApplicationMailer
default from: 'user@email.com'
def notification_email
@employees = Employee.all
mail(to: 'recipient@email.com',
subject: 'Reminder for missing documents')
end
end
所以我可以在我的 HTML 模板中获取所有员工的列表,并且我正在使用这样的 If 语句:
<% if employee.documents.length < Document.all.count %>
过滤掉所有文档的员工。 但我想在邮件本身中过滤它们。 由于我是初学者,因此找不到解决方法。请帮忙。
Rails 7 内置了这个
Employee.where.associated(:documents)
我认为以下内容可能适合您:
Employee
.left_outer_joins(:documents)
.group('employees.id')
.having("COUNT(documents.id) < #{Document.count}")
这些问题非常令人困惑,但是如果您有一个文档列表并且想要找到与所有或部分记录匹配的员工,您可以通过分组并使用必须在组上设置条件来实现:
Employee
.left_joins(:documents)
.where(documents: { id: documents })
.group(:id)
# HAVING COUNT("documents"."id") < 7
.having(Document.arel_table[:id].count.lt(documents.size))
这会给那些没有匹配所有文档但可能有一些的用户。可以使用 eq
、lteq
、gt
或 gteq
代替 lt
(小于)来简单地更改条件。
在 Postgres 上,您可以使用 COUNT(documents.*)
代替:
.having(Document.arel_table[Arel.star].count.lt(documents.size))