Posted over 9 years ago. Visible to the public.

Rails: When defining scopes with class methods, don't use `self`

Sometimes it is useful to define a named scope by implementing a static method with the scope's name on the scoped class. For instance, when a method should decide which existing scope should be the next link in the scope chain. Take this class for example:

Copy
class Meal < ActiveRecord::Base named_scope :for_date, lambda { |date| :conditions => { :date => date }} named_scope :with_meat, :conditions => { :meat => true } named_scope :without_meat, :conditions => { :meat => false } def self.suitable_for(user) if user.vegetarian? without_meat else with_meat end end end

You can now say:

Copy
Meal.for_date(Date.today).suitable_for(current_user)

The suitable_for method will now pick the correct meals depending on whether the user is a vegetarian or a carnivore.

Don't use self when defining scopes as class methods

In Rails 2 and 5 (not 3, not sure about 4) there is one caveat you should know about: Don't ever use self in a class method that is supposed to be used as a scope. Because of the way scopes work, this will discard any previous scopings in the chain link.

Say we want to change the suitable_for method so carnivores get meals both with and without meat. This would be wrong:

Copy
def self.suitable_for(user) if user.vegetarian? without_meat else self end end

With this, the scope chain Meal.for_date(Date.today).suitable_for(current_user) would return all meals, not only those of today. Do this instead:

Copy
def self.suitable_for(user) if user.vegetarian? without_meat else all # for Rails 2 use `scoped({})` instead of `all` end end

Note how we're returning #all instead of self. This ensures that we're preserving the upstream scope chain.

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for old versions of Ruby on Rails (3.2 and 2.3).

Owner of this card:

Avatar
Henning Koch
Last edit:
15 days ago
by Tobias Kraze
Keywords:
relation, activerecord
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more