Как объединить разные области применения в Rails 3? - PullRequest
1 голос
/ 14 марта 2012

В моем приложении rails есть следующие именованные области:

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

У меня проблемы с написанием того, в котором сочетается «опубликовано» и «скоро прочесано». Вот что я попробовал.

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

Есть идеи?

1 Ответ

3 голосов
/ 14 марта 2012

Рельсы 2: named_scope :public, :status => ['published', 'coming_soon']
Рельсы 3: scope :public, where(:status => ['published', 'coming_soon'])

Rails увидит массив и будет использовать оператор IN в sql.

Примечание. Другой подход (цепочка существующих областей действия) Article.published.coming_soon НЕ будет работать, потому что Article не может быть одновременно обоими этими вещами или быть подмножеством друг друга.

Еще одно примечание: Осторожно, когда вы хотите, чтобы что-то зависело от параметра переменной Например, если вы хотите «будущую встречу» для системы планирования, вы можете написать
[Это неверно ]

Рельсы 2: named_scope :upcoming_appts, :conditions => (['appt_dt > ?', Time.now])
Рельсы 3: scope :upcoming_appts, where(['appt_dt > ?', Time.now])

Однако есть проблема: Time.now будет оцениваться при первой оценке класса , а не при оценке самой области .
Чтобы преодолеть это, вы используете лямбду (глупое имя, но в основном означает анонимную функцию - или, проще говоря, «функцию, которая на самом деле не имеет имени») следующим образом:

[Это действует ]

Рельсы 2: named_scope :upcoming_appts, lambda {:conditions => (['appt_dt > ?', Time.now])}
Рельсы 3: scope :upcoming_appts, lambda {where(['appt_dt >= ?', Time.now])}

Эта область теперь будет оцениваться во время выполнения каждый раз, когда она используется, поэтому Time.now будет фактической текущей датой-временем.

...