ActiveRecord’s named_scopes are awesome, but I recently run into something less awesome about it: It doesn’t merge the
:select option of nested scopes.
So let’s look something like that:
class Profile::Business < Profile::Profile # ... some code ... named_scope(:by_popularity, :select => "profile_profiles.*, count(profile_fans.member_id) AS fan_count", # ... some more stuff for the scope :order => "fan_count DESC" ) # ... some more code ... end
And we use the named scope like this:
Profile::Business.by_popularity.find(:all, :select => 'profile_profile.*')
Should work, shouldn’t it? But as you might have guessed, it’s where ActiveRecord is exploding by throwing an
Mysql::Error: Unknown column 'fan_count' in 'order clause':
If you look at the rails log, you should see something like that:
Profile::Business Load (0.017810) SELECT profile_profiles.* FROM `profile_profiles` INNER JOIN [... some more SQL ...]
Yes, my first though was ‘Dude, where’s my SELECT?’. Turns out ActiveRecord doesn’t merge them it just use the last
:select it encounters. In my case the workaround was easy by moving the
class Profile::Business < Profile::Profile # ... some code ... named_scope(:by_popularity, :select => "profile_profiles.*", # ... some more stuff for the scope :order => "count(profile_fans.member_id) DESC" ) # ... some more code ... end
Crisis averted in this case, but it still leaves an uneasy feeling. And of course, the documentation says nothing about that.
Oh well… Someone proposed a patch for this problem and let’s hope it makes it into a Rails release.