Frage

Ich mag Aufzeichnungen auf einer Kombination von created_on finden> = some Datum und Namen in einiger Namensliste.

Für „> =“ Ich würde SQL-Zustand verwenden. Für „IN“ Ich muß einen Hash von Bedingungen verwenden würde, wo der Schlüssel ist. Name und der Wert ist die Anordnung von Namen

Gibt es eine Möglichkeit, die beiden zu kombinieren?

War es hilfreich?

Lösung

Sie können Scopes verwenden in Schienen 2.1 und höher

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

dann können Sie tun,

Test.created_after_2005.named_fred

Oder können Sie eine Lambda geben named_scope so dass Sie in Argumente zu übergeben

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

dann können Sie tun,

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

Andere Tipps

Wenn Sie eine ältere Version Rails verwenden, Honza Abfrage ist in der Nähe, aber Sie müssen Klammern für die Saiten hinzuzufügen, die in der IN-Bedingung gestellt bekommen:

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

Mit IN kann ein Mischbeutel sein: es ist am schnellsten für ganze Zahlen und langsamsten für eine Liste von Strings. Wenn Sie sich nur einen Namen mit finden, verwenden Sie auf jeden Fall einen Gleichheitsoperator:

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

Die kühle Sache über named_scopes ist, dass sie auf Sammlungen arbeiten auch:

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

@post = Post.published

@posts = current_user.posts.published

Weitere Informationen über named_scopes siehe Ryan Ankündigung und die auf 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

Wenn Sie in Variablen auf Ihre Bereiche passieren gehen haben Sie einen Lambda verwenden.

Sie können die Kette die where-Klausel:

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

Die genannten Bereiche bereits vorgeschlagen wurden, sind ziemlich gut. Der klassische Weg, es zu tun wäre:

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

Ich glaube, ich bin entweder einfache AR Finders oder Searchgasm .

scroll top