Das Mischen Active finden Bedingungen
-
01-07-2019 - |
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?
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