混合ActiveRecord查找条件

时间:2020-03-05 18:58:58  来源:igfitidea点击:

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

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

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

解决方案

回答

我们可以在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")

回答

有关named_scopes的更多信息,请参见Ryan的公告和named_scopes上的Railscast。

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。

回答

已经提出的命名范围非常好。做到这一点的经典方法是:

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

回答

如果我们使用的是旧版本的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])

回答

我想我或者要使用简单的AR查找器,或者要使用Searchgasm。

回答

named_scopes的酷之处在于它们也可以处理集合:

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

@post = Post.published

@posts = current_user.posts.published