Rails 3.1 named_scope - PullRequest
       0

Rails 3.1 named_scope

4 голосов
/ 26 декабря 2011

Что такое Rails 3.1 для написания кода ниже:

named_scope :min_2_items_last_90_days, {
    :include => { :orders => :order_items },
    :conditions => ['orders.created_at >= ?', 90.days.ago],
    :group   => 'people.id',
    :having => 'COUNT(order_items.id) >= 2'
  }

Ответы [ 2 ]

7 голосов
/ 26 декабря 2011

При записи как

scope :min_2_items_last_90_days, where(...)

синтаксически правильно, вероятно (как и ваш исходный код) не совсем то, что вы думаете.

В обоих случаях 90.days.ago оценивается только один раз, когда загружается класс, поэтому 90 дней всегда будут 90 днями до последнего перезапуска приложения. Если вы не перезагружали свое приложение в течение 10 дней, вы бы действительно смотрели на материалы, созданные за последние 100 дней. Вы не заметите этого в процессе разработки, потому что ваш исходный код постоянно перезагружается (и, следовательно, 90.days переоценивается).

Вместо этого вы должны сделать

scope :min_2_items_last_90_days, lambda { where('orders.created_at >= ?', 90.days.ago).includes(...) ... }

, который гарантирует, что условия будут переоцениваться при каждом использовании области действия.

2 голосов
/ 26 декабря 2011
scope :min_2_items_last_90_days, lambda { where('orders.created_at >= ?', 90.days.ago).includes(:orders => :order_items).group('people.id').having('COUNT(order_items.id) >= 2') }

Примечание (потому что это легко забыть) : Использование лямбда-выражения обеспечивает повторную оценку условий при каждом вызове области (см. Также документы по области действия ).И здесь необходима переоценка из-за выражения 90.days.ago - , которое вы обязательно хотите, чтобы 90.days.ago оценивалось каждый раз, когда область называется .Без лямбды переоценка не произойдет, и выражение 90.days.ago будет оценено (только) при запуске сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...