2008-09-17 15 views
8

Ich möchte Datensätze auf einer Kombination von created_on> = einige Datum und Name in einer Liste von Namen finden.Mixing ActiveRecord find Bedingungen

Für "> =" müsste ich sql Bedingung verwenden. Für "IN" müsste ich einen Hash der Bedingungen verwenden, wo der Schlüssel ist: name und der Wert ist das Array von Namen.

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

Antwort

26

Sie können Scopes in Schienen verwenden 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

Test.created_after_2005.named_fred 

tun Sie können auch 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") 
1

Für mehr auf named_scopes sehen Ryan's announcement und die Railscast on 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 wollen Sie ein Lambda verwenden.

0

Die bereits vorgeschlagenen Bereiche sind ziemlich gut. Der clasic Weg, es zu tun wäre:

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

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:

Die Verwendung von IN kann eine gemischte Sache sein: Es ist am schnellsten für ganze Zahlen und am langsamsten für eine Liste von Strings. Wenn Sie sich nur einen Namen mit finden, verwenden Sie auf jeden Fall ein Operator ist gleich:

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

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

2

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

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

@post = Post.published 

@posts = current_user.posts.published 
1

Sie können Kette der where Klausel:

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