简体   繁体   中英

Rails includes associations with left join conditions

Consider these two associated models, Program and SpentFinance :

class Program < ApplicationRecord
  has_many :spent_finances
end

class SpentFinance < ApplicationRecord
end

Each spent finance has a time_period_type , such as 'year' or 'month' .

How can I retrieve all programs, and at the same time preload all associated spent_finances associated with a program that have a certain time_period_type ?

Note:

  • The query must retrieve ALL programs, including programs that do not have any spent finances of the requested time period type.
  • Should provide a way to programmatically change the time_period_type in the query

These are the attempts I've made at cracking this problem.

First attempt

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

This doesn't work, because it filters out programs that don't have spent finances with the specified time period type. (It adds the time_period_type condition to the WHERE clause and not the JOIN ON clause.)

Second attempt

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

This works (the last line does not execute another query), and indeed it is the officially recommended solution . However, it doesn't allow me to programmatically specify the desired time_period_type . For example, if I want to do a similar query as above, but change the time_period_type to 'month' , then I would have to add another association has_many :monthly_spent_finances .

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM