混合ActiveRecord查找条件

时间:2008-09-17 14:14:13

标签: ruby-on-rails ruby activerecord

我想在某些名称列表中查找created_on> =某个日期和名称组合的记录。

对于“> =”我必须使用sql条件。对于“IN”,我必须使用条件的哈希,其中键是:name,值是名称数组。

有没有办法将两者结合起来?

7 个答案:

答案 0 :(得分:27)

您可以在rails 2.1及更高版本中使用命名范围

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

然后你可以做

Test.created_after_2005.named_fred

或者你可以给named_scope一个lambda,允许你传入参数

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

然后你可以做

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

答案 1 :(得分:7)

如果你使用的是旧版本的Rails,Honza的查询很接近,但是你需要为处于IN条件的字符串添加括号:

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

使用IN可以是一个混合包:它对于整数来说最快,对于字符串列表来说最慢。如果您发现自己只使用一个名称,请务必使用等于运算符:

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

答案 2 :(得分:2)

named_scopes的一个很酷的事情是它们也在集合上工作:

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

@post = Post.published

@posts = current_user.posts.published

答案 3 :(得分:1)

有关named_scopes的更多信息,请参阅Ryan's announcementRailscast 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

如果要将变量传递到范围,则必须使用lambda。

答案 4 :(得分:1)

您可以链接where子句:

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

答案 5 :(得分:0)

已经提出的命名范围非常好。经典的方法是:

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

答案 6 :(得分:0)

我想我要么使用简单的AR查找器,要么使用Searchgasm