Slick23
Slick23

Reputation: 5907

How to combine different scopes in Rails 3?

I have the following named scopes in my rails app:

  scope :published, :conditions => {:status => 'published'}
  scope :coming_soon, :conditions => {:status => 'coming_soon'}
  scope :in_development, :conditions => {:status => 'in_development'}
  scope :cancelled, :conditions => {:status => 'cancelld'}

I'm having trouble writing one that combines "published" and "combing soon." Here's what I've tried.

  scope :public, :conditions => {"status == published || status == coming_soon"}

Any ideas?

Upvotes: 1

Views: 426

Answers (1)

Michael Durrant
Michael Durrant

Reputation: 96544

Rails 2: named_scope :public, :status => ['published', 'coming_soon']
Rails 3: scope :public, where(:status => ['published', 'coming_soon'])

Rails will see the array and use the IN operator in the sql.

An a note: The other approach (chain existing scopes) of Article.published.coming_soon would NOT work because an Article can't be both of those things at the time time or be a subset of each other.

Another note: Careful when you want something dependent on a variable parameter. For example say you wanted "future appointment" for a scheduling system, you might write
[This is invalid]

Rails 2: named_scope :upcoming_appts, :conditions => (['appt_dt > ?', Time.now])
Rails 3: scope :upcoming_appts, where(['appt_dt > ?', Time.now])

However there's a problem: The Time.now will get evaluated the first time the class is evaluated not when the scope itself is evaluated.
To overcome this you use a lambda (silly name but basically means anonymous function - or to put it even simpler 'a function that doesn't actually have a name') as follows:

[This is valid]

Rails 2: named_scope :upcoming_appts, lambda {:conditions => (['appt_dt > ?', Time.now])}
Rails 3: scope :upcoming_appts, lambda {where(['appt_dt >= ?', Time.now])}

This scope will now get evaluated at execution time each time - it is used - so Time.now will be the actual current date-time.

Upvotes: 3

Related Questions