Rails includes with conditions

ruby-on-rails, sql

Solution

According to this guide Active Record Querying

You can specify conditions on includes for eager loading like this

Person.includes(:notes).where("notes.important", true)

It recommends to use `joins` anyway.

A workaround for this would be to create another association like this

class Person < ActiveRecord::Base
  has_many :important_notes, :class_name => 'Note', 
           :conditions => ['important = ?', true]
end

You would then be able to do this

Person.find(:all, include: :important_notes)

Problem

Is is possible in Rails > 3.2 to add conditions to the join statement generated by the `includes` method? Let's say I have two models, Person and Note. Each person has many notes and each note belong to one person. Each note has an attribute `important`. I want to find all the people preloading only the notes that are important. In SQL that will be: ``` SELECT * FROM people LEFT JOIN notes ON notes.person_id = people.id AND notes.important = 't' ``` In Rails, the only similar way to do that is using `includes` (note: `joins` won't preload notes) like this: ``` Person.includes(:notes).where(:important, true) ``` However, that will generate the following SQL query which returns a different result set: ``` SELECT * FROM people LEFT JOIN notes ON notes.person_id = people.id WHERE notes.important = 't' ``` Please, notice that the first resultset includes all the people and the second one only the people associated to important notes. Also notice that :conditions are deprecated since 3.1.

Original source

Related problems