Rails包括与左连接条件的关联

时间:2016-12-21 09:54:13

标签: ruby-on-rails activerecord

考虑这两个相关模型,ProgramSpentFinance

class Program < ApplicationRecord
  has_many :spent_finances
end

class SpentFinance < ApplicationRecord
end

每个已用完资金都有time_period_type,例如'year''month'

如何检索所有程序,同时预加载与具有特定spent_finances的程序关联的所有关联time_period_type

注意:

  • 查询必须检索所有程序,包括没有所请求时间段类型的任何花费资金的程序。
  • 应提供以编程方式更改查询中的time_period_type的方法

这些是我在解决这个问题时所做的尝试。

首次尝试

Program
.references(:spent_finances)
.includes(:spent_finances)
.merge(SpentFinance.where(time_period_type: time_period_type))

这不起作用,因为它会过滤掉那些没有花费指定时间段类型的财务的程序。 (它将time_period_type条件添加到WHERE子句而不是JOIN ON子句。)

第二次尝试

class Program < ApplicationRecord
  has_many :yearly_spent_finances,
    -> { where(time_period_type: 'year') },
    className: 'SpentFinance'
end

programs = Program.references(:yearly_spent_finances).includes(:yearly_spent_finances)

programs[0].yearly_spent_finances

这样可行(最后一行不执行另一个查询),实际上它是officially recommended solution。但是,它不允许我以编程方式指定所需的time_period_type。例如,如果我想执行与上面类似的查询,但将time_period_type更改为'month',那么我将不得不添加另一个关联has_many :monthly_spent_finances

1 个答案:

答案 0 :(得分:0)

受到首次尝试的启发,您希望加入加入,请尝试以下操作:

Program.includes(:spent_finances).where(spent_finances: {time_period_type: time_period_type} ).references(:spent_finances)