This references changeset [8054] and tickets #9923 and #10012.
First of all, I want to say that I *love* having :joins => :association as a shorthand for an inner join. It's a great idea.
Unfortunately the patch that was applied in [8054] treats :joins => :associations as a specialization of find_with_associations rather than as a specialization of add_joins!.
As a result, :include is now somewhat broken and, well, so is :joins.
1 - conflicts with :include and :joins
:include has always meant an outer join. However, now if you specify a non-string :joins option, your :includes no longer eager load and are no longer outer joins. As in:
Author.find(:all, :include => :should_be_outer, :joins => :should_be_inner)
is functionally equivalent to:
Author.find(:all, :joins => [:should_be_inner, :should_be_outer])
2 - non-string :joins are extremely inefficient
If you examine the sql generated by the following:
Author.find(:all, :joins => :contributions)
You can see that all columns from authors and all columns from contributions are being selected, even though none of the contributions columns will ever be used by an instantiated record.
On top of that, it's impossible to supply a :select argument (because it's a specialization of find_with_associations) which pretty much guarantees that your resulting dataset will have more rows than you need.
A different approach
Rather than treat :joins => :association as a specialization of find_with_associations, it should be a specializtion of add_joins! - that way the semantics of both :include and :joins is left intact.
Specifying Author.find(:all, :joins => :contributions) would behave exactly as if you had specified Author.find(:all, :joins => 'inner join contributions on contributions.author_id = authors.id').
When examining my patch please consider that:
- it undoes many of the changes from [8054] so it looks really chatty and complex. If you apply the patch and then do "svn diff -r 8053 activerecord/lib/active_record/base.rb activerecord/lib/active_record/associations.rb activerecord/lib/active_record/calculations.rb " you'll see that it's actually a very straight-forward change.
- I have not updated the ar_joins_test.rb file because many of the tests in there operate on the assumption that :join => :something should return the same number of rows that :include => :something would have done. Seeing that I fundamentally disagree with that feature I've left those tests unchanged, pending feedback from others.