Смешивание ActiveRecord найти условия - PullRequest
9 голосов
/ 17 сентября 2008

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

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

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

Ответы [ 7 ]

27 голосов
/ 17 сентября 2008

Вы можете использовать именованные области в рельсах 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

Или вы можете дать named_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")
7 голосов
/ 17 сентября 2008

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

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

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

Person.find(:all, :conditions => ["created_at > ? AND name = ?", date, name])
2 голосов
/ 24 сентября 2008

Отличительной особенностью named_scopes является то, что они работают и с коллекциями:

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

@post = Post.published

@posts = current_user.posts.published
1 голос
/ 01 мая 2013

Вы можете связать предложение where:

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

1 голос
/ 17 сентября 2008

Подробнее о named_scopes см. Объявление Райана и Railscast для named_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

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

0 голосов
/ 18 сентября 2008

Я думаю, что я собираюсь использовать простые AR-искатели или Searchgasm .

0 голосов
/ 17 сентября 2008

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

names = ["dave", "jerry", "mike"]
date = DateTime.now
Person.find(:all, :conidtions => ["created_at > ? AND name IN ?", date, names])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...