Mixing ActiveRecord find Conditions

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

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.

Is there a way to combine the two?


You can use named scopes in rails 2.1 and above

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

then you can do


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

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

then you can do


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:

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:

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

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

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

@post = Post.published

@posts = current_user.posts.published

For more on named_scopes see Ryan's announcement and the Railscast 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 } } }

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

You can chain the where clause:

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

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])

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

Need Your Help

bash script, create array of all files in a directory

arrays bash shell while-loop

I have a directory myDir of many .html files. I am trying to create an array of all the files in the directory so I might be able to index the array and be able to refer to particular html files ...

Print a list of space-separated elements in Python 3

python python-3.x pretty-print

I have a list L of elements, say natural numbers. I want to print them in one line with a single space as a separator. But I don't want a space after the last element of the list (or before the f...