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:
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...
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.
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.