having a play with scopes tonight in rails 3, and trying to get my head around what lambda does?
What I am trying to achieve in this example is get a list of country names (:name) from my countries model which is associated with my recipe model. A recipe belongs_to country and a country has many recipes.
I would like to order the recipes by amount of times they appear in a recipe, starting with the highest..
So i am trying this in my recipe model ( or should I do it within the country model?, but then that wouldn’t work would it as my country model is pre populated with 1 instance of every country in the world)
scope :top_countries, lambda { joins(:countries).merge(Country.name).order("name DESC") }
however i get this error message
undefined method `default_scoped?' for "Country":String
my controller
@toprankingcountry = Recipe.top_countries
obviously my understanding is not what i thought and would appreciate some pointers/assistance
Thanks
I believe the problem is with merge(Country.name) part. joins(:countries) returns ActiveRecord::Relation instance. Its merge method expects one argument which is another instance of a ActievRecord::Relation, whereas you merge string Country.name.
Generally speaking, getting a list of top countries effectively means getting a list of Countries order by some additional condition. So I'd put this logic into a Country model.
class Country
has_many :recipes
def self.top_countries
joins(:recipes).
select('countries.*, count(*) AS recipes_count').
group('countries.id').
order('recipes_count DESC')
end
end
Also if you are using RDBMS which cannot figure out dependent rows on its own (like PostgreSQL < 9.1) you'll have to manually list all the columns in group by clause.
get a list of country names (:name) from my countries model which is associated with my recipe model (instance)
I believe it is impossible to achieve what you described as is because a country has_many recipes, not vice versa