Вопрос

Я хочу найти записи по комбинации созданных_on >= некоторой даты И имени В некотором списке имен.

Для ">=" мне придется использовать условие sql.Для «IN» мне пришлось бы использовать хеш условий, где ключ — :name, а значение — массив имен.

Есть ли способ объединить эти два процесса?

Это было полезно?

Решение

Вы можете использовать именованные области видимости в рельсах 2.1 и выше.

Class Test < ActiveRecord::Base
  named_scope :created_after_2005, :conditions => "created_on > 2005-01-01"
  named_scope :named_fred, :conditions => { :name => "fred"}
end

тогда ты сможешь сделать

Test.created_after_2005.named_fred

Или вы можете указать name_scope лямбду, позволяющую передавать аргументы.

Class Test < ActiveRecord::Base
  named_scope :created_after, lambda { |date| {:conditions => ["created_on > ?", date]} }
  named_scope :named, lambda { |name| {:conditions => {:name => name}} }
end

тогда ты сможешь сделать

Test.created_after(Time.now-1.year).named("fred")

Другие советы

Если вы используете более старую версию Rails, запрос Honza близок, но вам нужно добавить круглые скобки для строк, которые помещаются в условие IN:

Person.find(:all, :conditions => ["created_at > ? AND name IN (?)", date, names])

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

Person.find(:all, :conditions => ["created_at > ? AND name = ?", date, name])

Самое замечательное в Name_scopes то, что они работают и с коллекциями:

class Post < ActiveRecord::Base
  named_scope :published, :conditions => {:status => 'published'}
end

@post = Post.published

@posts = current_user.posts.published

Дополнительную информацию об именованных_областях см. Заявление Райана и Railscast на Name_scopes

class Person < ActiveRecord::Base
  named_scope :registered, lambda { |time_ago| { :conditions => ['created_at > ?', time_ago] } }
  named_scope :with_names, lambda { |names| { :conditions => { :names => names } } }
end

Если вы собираетесь передавать переменные в свои области видимости, вам придется использовать лямбду.

Вы можете связать where пункт:

Person.where(name: ['foo', 'bar', 'baz']).where('id >= ?', 42).first

Уже предложенные именованные области вполне подходят.Классический способ сделать это:

names = ["dave", "jerry", "mike"]
date = DateTime.now
Person.find(:all, :conidtions => ["created_at > ? AND name IN ?", date, names])

Думаю, я либо воспользуюсь простыми AR-искателями, либо Поисковый газ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top