используя лямбду в находке в рельсах - PullRequest
2 голосов
/ 15 августа 2010

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

1

coll = paginate(:all, lambda {{:conditions => ['status = ? AND expires < ?', 'a', DateTime.now]}}, :select => Constants::POST_FIELDS,
                   :order => 'posts.ratings DESC', :include => [{:poster => :poster_friends}, :category], :per_page => Constants::LISTINGS_PER_PAGE,
                   :page => page)

Когда этот вызов выполняется, он просто игнорирует условия в сгенерированном запросе.1007 * 2

Если я попробую это в named_scope, я получу ошибку вроде ..

named_scope :featured_all, lambda {{:conditions => ['status = ? AND expires < ?', 'a', DateTime.now], order => 'posts.ratings DESC', :include => [{:poster => :poster_friends},  :category],
            :select => Constants::POST_FIELDS}}

Ошибка именованной области:

/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/core_ext/hash/keys.rb:47:in `assert_valid_keys'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2101:in `with_scope'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:113:in `__send__'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:113:in `with_scope'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:174:in `method_missing'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:188:in `load_found'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:166:in `proxy_found'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:109:in `is_a?'
    /usr/lib/ruby/gems/1.8/gems/hirb-0.3.1/lib/hirb/formatter.rb:78:in `determine_output_class'
    /usr/lib/ruby/gems/1.8/gems/hirb-0.3.1/lib/hirb/formatter.rb:48:in `format_output'
    /usr/lib/ruby/gems/1.8/gems/hirb-0.3.1/lib/hirb/view.rb:213:in `render_output'
    /usr/lib/ruby/gems/1.8/gems/hirb-0.3.1/lib/hirb/view.rb:126:in `view_output'

Для # 1,Что я делаю не так, почему игнорирует условия?

Для # 2 Почему эта ошибка?А также, как я могу передать параметр: page и per_page, чтобы ограничить запрос в named_scope.

Спасибо

Ответы [ 2 ]

1 голос
/ 16 августа 2010

Ваш вариант использования не гарантирует named_scope. Вы можете написать обычный искатель следующим образом:

coll = paginate(:select     => Constants::POST_FIELDS,
                :conditions => ['status = ? AND expires < ?', 'a', DateTime.now],
                :include    => [{:poster => :poster_friends}, :category],
                :order      => 'posts.ratings DESC',  
                :per_page   => Constants::LISTINGS_PER_PAGE,
                :page => page)

Метод paginate эквивалентен all, поэтому вам не нужно указывать спецификатор области действия :all для метода paginate.

Значение времени рассчитывается при выполнении запроса. Это не похоже на named_scope, где вы должны использовать лямбду для того же эффекта.

Если вам нужно использовать named_scope, выполните следующие действия:

named_scope :featured_all, lambda {{
                :select     => Constants::POST_FIELDS,
                :conditions => ['status = ? AND expires < ?', 'a', DateTime.now],
                :include    => [{:poster => :poster_friends}, :category],
                :order      => 'posts.ratings DESC'
               }}

Теперь вы можете использовать named_scope следующим образом

Post.feature_all.paginate(:per_page => Constants::LISTINGS_PER_PAGE, 
                          :page => page)
0 голосов
/ 15 августа 2010

В названном объеме отсутствует : перед ключом заказа.Это может взорвать названную область.В противном случае все выглядит хорошо.

Тем не менее, вам не нужно использовать лямбду, чтобы получить записи, относящиеся к текущему времени.Ваша база данных предоставляет методы, которые делают подобное.Например, если вы используете MySQL, вы можете использовать:

named_scope(:featured_all, {
  :conditions => "status = 'a' AND expires < UTC_TIMESTAMP()",
  :order => 'posts.ratings DESC',
  :include => [{:poster => :poster_friends}, :category],
  :select => Constants::POST_FIELDS
})

UTC_TIMESTAMP() - специфичная для MySQL функция, которая возвращает текущую дату и время в UTC (какие Rails должны хранить ваши DateTimes как уже).

...