Feature Request: Auto-infer .includes from .where with ActiveRecord queries

In the following snippet, can’t the includes being inferred from the where clause?

Order.includes(:items).where(:items => { :category => [1,2,3] })

Can’t the includes be inferred from the where clause?

Order.where(:items => { :category => [1,2,3] })

Would this conflict with any existing usages of the where clause and hashes?

The hazard with auto-inferring here (IMHO) is that it makes forgetting a joins clause go from a runtime error to a silent logic error. If I *meant* to build this chain:

Order.joins(:items).where(:items => { :category => [1,2,3] })

but forgot the joins, I've now got a query that returns *all* Orders. Not a big deal in this case, but could be a recipe for disaster if the conditions in the where are for access control...

--Matt Jones

Ugh, posting before testing - this actually only happens if you have a condition in the where that evaluates to true for NULLs. I still think the overall criticism stands, however.

--Matt Jones

I believe it cant be inferred, thats why:
Order.where(:items => {:name => “X”})
SELECT orders.* FROM orders WHERE orders.name = ‘X’ <== Clearly wrong.
Order.includes(:item).where(:items => {:name => “X”})
SELECT orders.id AS t0_r0, orders.item_id AS t0_r1, … , items.id AS t1_r0, items.name AS t1_r1, … FROM orders LEFT OUTER JOIN items ON items.id = orders.item_id WHERE orders.name = ‘X’
Selects every column from Order and Item using LEFT OUTER JOINOrder.joins(:item).where(:items => {:name => “X”})
SELECT orders.* FROM orders INNER JOIN items ON items.id = orders.item_id WHERE items.name = ‘X’
INNER JOINs selection without selecting every fieldOrder.includes(:item).joins(:item).where(:items => {:name => “X”})
SELECT orders.id AS t0_r0, orders.item_id AS t0_r1, … , items.id AS t1_r0, items.name AS t1_r1, … FROM orders INNER JOIN trackers ON trackers.id = issues.tracker_id WHERE trackers.name = ‘X’
INNER JOINs selection selecting every field

Each options have its own behaviour, and is suitable for one case.

Everton