2008-09-17 17 views
8

Quiero buscar registros en una combinación de created_on> = alguna fecha Y nombre EN alguna lista de nombres.Mixing ActiveRecord find Condiciones

Para "> =" Tendría que usar la condición sql. Para "IN" tendría que usar un hash de condiciones donde la clave es: name y el valor es la matriz de nombres.

¿Hay alguna manera de combinar los dos?

Respuesta

26

Puede utilizar los ámbitos mencionados en los carriles 2.1 y anteriores

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

entonces puede hacer

Test.created_after_2005.named_fred 

o se puede dar named_scope un lambda que le permite pasar de argumentos

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

entonces usted puede hacer

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

Para más información sobre named_scopes ver Ryan's announcement y la 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 

Si va a pasar en las variables a sus alcances que tiene que utilizar una lambda.

0

Los ámbitos nombrados ya propuestos son bastante buenos. La forma más clásico de hacerlo sería:

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

Si estás usando una edad avanzada rieles de versión, consulta de Honza está cerca, pero hay que añadir entre paréntesis para las cadenas que quedan colocados en el estado en:

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

El uso de IN puede ser una bolsa mixta: es más rápida para enteros y más lenta para una lista de cadenas. Si usted se encuentra el uso de un solo nombre, sin duda utilizar un operador de igualdad:

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

Creo que cualquiera que voy a utilizar buscadores AR simples o Searchgasm.

2

Lo bueno de named_scopes es que trabajan en colecciones también:

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

@post = Post.published 

@posts = current_user.posts.published 
1

Usted puede encadenar la cláusula where:

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