Pregunta

Quiero encontrar registros en una combinación de creado_en >= alguna fecha Y nombre EN alguna lista de nombres.

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

¿Hay alguna manera de combinar los dos?

¿Fue útil?

Solución

Puede utilizar ámbitos con nombre en Rails 2.1 y superiores

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

entonces puedes hacer

Test.created_after_2005.named_fred

O puedes darle a name_scope una lambda que te permita pasar 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 puedes hacer

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

Otros consejos

Si está utilizando una versión anterior de Rails, la consulta de Honza está cerrada, pero necesita agregar paréntesis para las cadenas que se colocan en la condición IN:

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

Usar IN puede ser una mezcla de cosas:es más rápido para números enteros y más lento para una lista de cadenas.Si usas solo un nombre, definitivamente usa un operador igual:

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

Lo bueno de Named_scopes es que también funcionan en colecciones:

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

@post = Post.published

@posts = current_user.posts.published

Para obtener más información sobre los ámbitos nombrados, consulte El anuncio de Ryan y el Railscast en nombrados_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 variables a sus ámbitos, debe usar una lambda.

Puedes encadenar el where cláusula:

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

Los ámbitos nombrados ya propuestos están bastante bien.La forma clásica de hacerlo sería:

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

Creo que voy a utilizar buscadores AR simples o gas de búsqueda.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top