Skip to content
brendan edited this page Sep 12, 2010 · 4 revisions

Was toying with calling this SexyConditions, since its basically about extending the
use of Arrays as ActiveRecord finder conditions, to serve as symbolic expressions ala
Lisp, (hence the Sex in S-Expression,) but frankly the name BetterConditions has been
in use in our shop’s vocabulary since it was created, and it stuck.

So what exactly does this do? It enables you to construct nested logical expressions
using symbolic prefix notation, such that [:and, ‘condition1’, ‘condition2’] produces
the fragment “(condition1) AND (condition2)”. Since it delegates back to sanitize_sql
it plays nicely with other extensions, like find_by_association as well as nesting ala…

[:and, [:or, [:not, {:status => ’suspended’}], {:username => ’root’}]], {:pass => "123"}]]

to produce something like the following SQL partial for conditions…

((NOT (status=‘suspended’)) OR (username=‘root’)) AND (pass=‘123’)

Some further examples:

class CreatePeople < ActiveRecord::Migration create_table :people do |t| t.column :name, :string t.column :job, :string t.column :age, :integer t.column :living, :boolean end end class Person < ActiveRecord::Base end

Use an array containing hashes or arrays to express OR…
Finds everyone who is either dead OR over 30 years old.

Person.find :all, :conditions => [{:living => false},[“age > ?”, 30]]

Using the :all predicate at the head of an array…
Finds everyone who is alive AND 30 years old or younger.

Person.find :all, :conditions => [:all, {:living => true},[“age <= ?”, 30]]

Using the :not predicate at the head of an array…
Finds everyone who is NOT named ‘Alice’.

Person.find :all, :conditions => [:not, {:name => ’Alice’}]

Nesting arrays within arrays… Ruby Arrays become S-Expressions…
Finds everyone who is NOT either of these
1.) dead or over 30
2.) alive and 30 or under


Person.find :all, :conditions => [:not,
  [{:living => false},["age > ?", 30]], 
  [:all, {:living => true},["age <= ?", 30]]
]
Clone this wiki locally