Ruby-on-rails 混合 ActiveRecord 查找条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/83674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:39:27  来源:igfitidea点击:

Mixing ActiveRecord find Conditions

ruby-on-railsrubyactiverecord

提问by Tony Pitale

I want to find records on a combination of created_on >= some date AND name IN some list of names.

我想在一些名称列表中查找 created_on >= some date AND name 组合的记录。

For ">=" I'd have to use sql condition. For "IN" I'd have to use a hash of conditions where the key is :name and the value is the array of names.

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

Is there a way to combine the two?

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

回答by Laurie Young

You can use named scopes in rails 2.1 and above

您可以在 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

then you can do

那么你可以做

Test.created_after_2005.named_fred

Or you can give named_scope a lambda allowing you to pass in arguments

或者你可以给 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

then you can do

那么你可以做

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

回答by Josh Schwartzman

If you're using an older version Rails, Honza's query is close, but you need to add parentheses for the strings that get placed in the IN condition:

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

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

Using IN can be a mixed bag: it's fastest for integers and slowest for a list of strings. If you find yourself using just one name, definitely use an equals operator:

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

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

回答by ismaSan

The cool thing about named_scopes is that they work on collections too:

named_scopes 很酷的一点是它们也适用于集合:

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

@post = Post.published

@posts = current_user.posts.published

回答by Sujoy Gupta

You can chain the whereclause:

您可以链接where子句:

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

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

回答by Sixty4Bit

For more on named_scopes see Ryan's announcementand the Railscast on named_scopes

有关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

If you are going to pass in variables to your scopes you have to use a lambda.

如果要将变量传递给作用域,则必须使用 lambda。

回答by Honza

The named scopes already proposed are pretty fine. The clasic way to do it would be:

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

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

回答by Tony Pitale

I think I'm either going to use simple AR finders or Searchgasm.

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