ActiveRecord - "includes" & "where" 获取 Nil 和 Not Nil 语句,以及其他属性

ActiveRecord - "includes" & "where" gettting Nil and Not Nil Statement, with other attributes

我想使用“.includes()”有效地获取结果。

我需要包含 Table 来检索非零的记录。我需要在查询中保留 included: true

使用 postgres。

角色有很多任务。

任务属于角色。

以下有效但从角色 table.

中获取错误记录
Task.includes(:role).where(included: true, roles: {doer: nil})

下一部分是我想要的想法...... 但显然 where 子句的 "roles" 值中的语法错误。

Task.includes(:role).where(
    included: true,
    roles: {
        doer != nil    #=> where 'doer' is not 'nil'
    })

我正在寻找一个高效的查询,这就是我进行包含的原因。 如果没有多个 where 查询,我不知道如何获得它。

如果您理解这个问题,但认为可以更好地提出更清楚的问题,请告诉我。除非使用多个 where 语句,否则我无法在任何地方找到此答案的任何线索。

像这样的东西怎么样:

Task.includes(:roles).where.not('roles.doer' => nil)

这是一个 rails 4-and-up 约定,对于 rails 3 它会是这样的:

Task.includes(:roles).where("roles.doer IS NOT NULL")

并且您不需要 included 属性,出于这些目的,可以将其从模型中删除。

因为你似乎确实需要 included(糟糕)

Task.includes(:roles).where('tasks.included' => true, 'roles.doer' => !nil)

Aaah.. 我多么喜欢 postgres.. 当你要求效率时,我认为这失败了,但我返回了正确的结果。如果你对选项进行基准测试,这是正确的(我认为)但速度很慢。

Task.joins('LEFT OUTER JOIN "roles" ON roles.user_id = user_id').where("tasks.included IS true AND roles.doer IS NOT NULL")

像这样写SQL语句?

Task.includes(:角色).where("included = 'true' AND roles.doer NOT 'nil'")

我希望尽可能避免使用字符串,所以我会使用以下内容:

Task.includes(:role).where(included: true).where.not(roles: { doer: nil })

如果您专门将 tasks table 上的 included 列设置为具有 NULL FALSE,您还可以将 where 调用压缩为单个调用,尽管这仍然只会启动一个查询:

Task.includes(:role).where.not(included: false, roles: { doer: nil })

就我个人而言,如果这些调用是司空见惯的,我希望在某些范围内对此进行一些清理。类似于:

scope :with_doer, -> { includes(:role).where.not(roles: { doer: nil }) }

因此生成的代码将更具可读性:

Task.with_doer.where(included: true)

您显然也可以将此模式扩展到 included: true 位。

请注意,ActiveRecord 查询是建立起来的,然后通过 "kicker" 被踢到数据库中,Rails 是通过 #inspect#to_a 偷偷摸摸地做的的时间。因此,您无需担心需要将 where 调用压缩为单个调用。