20

I'm using Rails 3.2 and I've got a database table in which I want to find all the rows that match the following criteria:

a = true and b = true and ( 0< c <1 or d=1), a, b, c, d are columns.

Can I have something like:

 Route.where(:a => true,
             :b => true,
             :c => 0..1 OR :d=1
             ).all          
halfer
  • 19,824
  • 17
  • 99
  • 186
Webspirit
  • 1,013
  • 3
  • 12
  • 18

3 Answers3

19

I may be wrong, but I don't think you could form that query using the Arel-based where function; you'd need to form up the database query string yourself.

Assuming you're using SQLite or Postgres:

Route.where("a = true and b = true and ((c > 0 and c < 1) or d = 1)").all

I haven't tested this code, but I suspect that might do the job for you. Note this is less 'portable' code; if you change the database you're using the query may break.

Rob d'Apice
  • 2,416
  • 1
  • 19
  • 29
  • 3
    `where('a = :true and b = :true and ((c > :lo and c < :hi) or d = :d', :true => true, :lo => 0, :hi => 1, :d => 1)` would be safer, different databases uses different things for "true". Or even `.where(:a => true, :b => true).where('c > :lo and c < :hi) or d = :d', ...)`. – mu is too short Jun 09 '12 at 06:18
16

In Rails 4 you can also do

Route.where(:a => true,:b => true,:c => [1,2]).all

This will find where c is 1 or 2.

user2031423
  • 347
  • 4
  • 7
4

I think Rob is right about arel not supporting OR yet. From the arel site:

The OR operator is not yet supported. It will work like this:

users.where(users[:name].eq('bob').or(users[:age].lt(25)))

The AND operator will behave similarly.

pepe
  • 555
  • 4
  • 8