Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3. Query for not true

I have a table called scheduled_sessions and a Boolean column called instructor_performed to check if the instructor did teach the class or not.

So I need to find all the records where the instructor didn't teach the class. But I can't do this: ScheduledSession.where(:instructor_performed => false) because if the cell is blank, it won't return that record. I just need all records that are NOT true.

like image 953
leonel Avatar asked Nov 30 '22 06:11

leonel


1 Answers

It sounds like your instructor_performed column can be true, false, or NULL, so you need to query for false or NULL, like this:

ScheduledSession.where(instructor_performed: [false, nil])

You could avoid this complexity if you'd set up your database table to disallow null values in that column. You can specify this constraint when you create the table in a migration:

add_column :scheduled_session, :instructor_performed, :boolean,
  null: false, default: false

or

create_table :scheduled_session do |t|
  t.boolean :instructor_performed, null: false, default: false
  ...
end

Or you can change the constraint for an existing column:

change_column_null :scheduled_session, :instructor_performed, false, false

In all of the above, we're setting the column to allow only true or false values, and we're telling it to use a default value of false. (Without setting the default, you can't add a no-nulls constraint because your existing data violates it.)

I almost always disallow nulls when I'm setting up boolean columns (unless I truly want tri-state attributes), because it lets me do this to find everything that's not true:

ScheduledSession.where(instructor_performed: false)

Note that other answers (now deleted) that encouraged use of an SQL fragment like "instructor_performed != true" won't work because SQL won't let you use = or != to match a NULL value. Kind of weird, but them's the rules. Instead SQL makes you do this:

SELECT * from scheduled_sessions WHERE instructor_performed IS NULL
  OR instructor_performed = FALSE;

which the above Rails where query hides from you somewhat, as long as you're still aware that you're searching for two values.

like image 185
Rob Davis Avatar answered Dec 14 '22 22:12

Rob Davis