Workaround for has_many :through overriding the :select clause
As I mentioned earlier a named_scope select clause will get overridden in a has_many :through.
class Grandparent has_many :grandchildren, :through => :children end class Grandchild named_scope :summed_ages_by_gender, :select => "SUM(age) as age", :group => :gender end Grandparent.first.grandchildren.summed_ages_by_gender #does not do what you want, because the through overrides the select
If you have a case where this isn’t acceptable, such when you have a complicated aggregate select that you would like to call on a has_many through, there is an ugly work-around. You can recreate the has_many :through, with joins in a scope on the child model, then return that in a method of the grandparent.
class Grandparent
def grandchildren
Grandchild.grandchildren.scoped({:conditions => ['grandparents.id = ?'], id})
end
end
class Grandchildren
named_scope :summed_ages_by_gender, :select => "SUM(age) as age", :group => :gender
named_scope :grandchildren, :joins => ['JOIN parents ON grandchildren.parent_id => parents.id', 'JOIN grandparents ON parents.grandparents_id = grandparents.id']
end
Grandparent.first.grandchildren.summed_ages_by_gender
#should work
Obviously I would not advise using this as a relationship model – it was one I just threw together for elucidation. And I haven’t run this exact code, but I have run the code it is a dummied up copy of, with great success.
Maybe I’ll try and come up with a patch to fix the original problem, but the through select logic is probably some of the most edge-case ridden in AR associations, so I am not sure how easy it would be.
Update: I made a ticket with a patch for the failing test, at least.