Pergunta

Eu quero encontrar registros em uma combinação de created_on,> = alguma data e nome em alguma lista de nomes.

Para "> =" Eu teria que usar condição sql. Para "IN" Eu teria que usar um hash de condições em que a chave é:. Nome e o valor é o conjunto de nomes

Existe uma maneira de combinar os dois?

Foi útil?

Solução

Você pode usar escopos no Rails 2.1 e acima chamado

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

então você pode fazer

Test.created_after_2005.named_fred

ou você pode dar named_scope um lambda que lhe permite passar argumentos

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

então você pode fazer

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

Outras dicas

Se você estiver usando uma velha Rails versão, consulta de Honza está perto, mas você precisa adicionar parênteses para as cordas que são colocados no estado em:

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

Usando IN pode ser um saco misturado: é mais rápido para inteiros e mais lento para uma lista de strings. Se você está usando apenas um nome, definitivamente usar um igual operador:

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

A coisa legal sobre named_scopes é que eles trabalham em coleções demasiado:

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

@post = Post.published

@posts = current_user.posts.published

Para saber mais sobre named_scopes ver anúncio de Ryan eo Railscast em 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

Se você estiver indo para passar variáveis ??para os escopos que você tem que usar um lambda.

Você pode encadear a cláusula where:

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

Os escopos nomeados já propostos são muito bem. A maneira clássica de fazer isso seria:

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

Eu acho que tanto vou usar localizadores AR simples ou Searchgasm .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top