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

22 views
Skip to first unread message

Nathan Broadbent

unread,
Apr 12, 2017, 1:25:52 PM4/12/17
to Ruby on Rails: Core
Hello,

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
end

class Record < ActiveRecord::Base
belongs_to :company
end

class User < ActiveRecord::Base
belongs_to :company
has_many :records, through: :company
end


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

and:

def records
Record.where(company_id: company_id)
end

... 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
Reply all
Reply to author
Forward
0 new messages