Michiel de Mare
Michiel de Mare

Reputation: 42420

Rails 3: scope is not true

How do I convert the following into something that works on sqlite and mysql? Note, internal is nullable.

  scope :external, where("internal is not true")

(In Rails 4, one can simply use:)

  scope :external, where.not(internal: true)

Upvotes: 2

Views: 1423

Answers (3)

Oleksandr Avoiants
Oleksandr Avoiants

Reputation: 1929

ActiveRecord is smart enough for doing this, just do:

scope :external, where(internal: [false, nil])

That would be transformed in similar SQL (with table name and quetes probably):

  • for PostgreSQL and SQLite internal IN ('f') OR internal IS NULL
  • for MySQL internal IN (0) OR internal IS NULL

If need more control you can use Arel:

scope :external,
  where(arel_table[:internal].eq(false).or(arel_table[:internal].eq(nil)))

Which would be:

  • for PostgreSQL and SQLite internal = 'f' OR internal IS NULL
  • for MySQL internal = 0 OR internal IS NULL

Remember, if you need to check NULL values in SQL always use IS NULL or IS NOT NULL expressions.

Expresions ... <> NULL, ... = NULL, ... IN (NULL) are evaluated as false for everything.

So, NULL <> NULL is false and NUL = NULL is false.

Upvotes: 4

12321
12321

Reputation: 36

Try scope :external, where('internal IN (?)', [false,nil])

Upvotes: 1

bricker
bricker

Reputation: 8941

Try scope :external, where(:internal => !true)

Upvotes: -1

Related Questions