Reputation: 2845
I have a User model which has the boolean attribute :sourced
I wanted to write the code below, but I get returned an empty array
User.where(sourced: false)
# User Load (2.0ms) SELECT "users".* FROM "users" WHERE "users"."sourced" = 'f' ORDER BY users.id DESC
# => []
However, this isn't the case, because there actually are records that have sourced set to false.
i.e, when I run
User.first.sourced #=> false
In my schema.rb file, it shows that the default value for the 'sourced' column is false
create_table "users", force: true do |t|
t.string "name"
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
t.string "password_digest"
t.string "remember_token"
t.boolean "admin", default: false
t.string "password_reset_token"
t.datetime "password_reset_sent_at"
t.text "admin_note", limit: 800
t.integer "applications_count"
t.string "admin_link"
t.boolean "sourced", default: false
t.boolean "told_admin"
end
What's going on here?
Upvotes: 0
Views: 586
Reputation: 3935
This is caused because you don't have a default value of false set in your migration, so it is saving it as nil which you aren't looking for. With duck typing nil == false so on the ruby level its false.
While you could do a query for false and nil... this is a bit cumbersome. Just set a default value in your database.
you can fix this with a migration
def up
#change column
change_column :users, :sourced, :boolean, default: false
# reload schema https://stackoverflow.com/a/8935621/793330
User.reset_column_information
# update the nils
User.find_each(&:save)
end
Always remember to set a default value for boolean values in your database. This will save you a ton of frustration in the future and also helps with validations by always setting a default value on the database level.
Also if you're using SQLite? perhaps its not typecasting properly does this work?
User.where(sourced: 0)
Upvotes: 1