I think has_many :through could be improved to use a WHERE instead of INNER JOIN, when possible


I was just wondering if it might be possible for has_many :through to generate a WHERE query sometimes, instead of always doing an INNER JOIN? For example:

class Company < ActiveRecord::Base

has_many :records


class Record < ActiveRecord::Base

belongs_to :company


class User < ActiveRecord::Base

belongs_to :company

has_many :records, through: :company


When you call user.records, I would expect it to just run a plain WHERE query, instead of doing an INNER JOIN. Rails already knows that the User belongs to the Company, and it knows that a Company has many Records, so I think it’s safe to skip the join in this case.

I imagine there are a lot of edge cases that could make this tricky, but I think it might be nice if trivial cases like this were supported.

I’m nervous about posting this message, because I have the feeling that I’m forgetting something obvious. I know I can write:

has_many :records, foreign_key: :company_id, primary_key: :company_id


def records

Record.where(company_id: company_id)


… but I think has_many :records, through: :company is nicer. Unless there’s a more idiomatic way to do this?

I’ve attached some test code using the ActiveRecord bug report template, but it’s not really a bug. It just demonstrates the current behavior of ActiveRecord.

Thanks for your time!

has_many_test.rb (1.84 KB)