Reputation: 6263
I use mysql on production and sqlite3 on my development.
When querying my database on development e.g.
@follow_ups = FollowUp.where(is_complete: false)
I get the sql below in my console
SELECT "follow_ups".* FROM "follow_ups" WHERE "follow_ups"."is_complete" = 'f'
sqlite evaluates 'f' as a truthy value so no follow_ups.is_complete = false are returned. In the database they are stored as true/false. From my investigations I found.
https://github.com/rails/rails/issues/10720
Rails 3 SQLite3 Boolean false
What should I do to get my boolean filters working? I would have thought this would be happening to more people.
See schema below
create_table "follow_ups", force: true do |t|
t.integer "contact_id"
t.integer "owner_id"
t.datetime "due_date"
t.string "comment"
t.boolean "is_complete", default: false
t.integer "created_by_user_id"
t.integer "updated_by_user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
See data and insertions below - done via rails console. As request in comments.
[30] pry(main)> FollowUp.create(contact_id: 1, due_date: Time.now, is_complete: true)
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "follow_ups" ("contact_id", "created_at", "due_date", "is_complete", "updated_at") VALUES (?, ?, ?, ?, ?) [["contact_id", 1], ["created_at", "2014-04-22 19:17:01.854402"], ["due_date", "2014-04-22 19:17:01.853540"], ["is_complete", "t"], ["updated_at", "2014-04-22 19:17:01.854402"]]
(1.7ms) commit transaction
#<FollowUp:0x0000010699c5a8> {
:id => 23,
:contact_id => 1,
:owner_id => nil,
:due_date => Tue, 22 Apr 2014 19:17:01 UTC +00:00,
:comment => nil,
:is_complete => true,
:created_by_user_id => nil,
:updated_by_user_id => nil,
:created_at => Tue, 22 Apr 2014 19:17:01 UTC +00:00,
:updated_at => Tue, 22 Apr 2014 19:17:01 UTC +00:00
}
[31] pry(main)> FollowUp.where(is_complete: true)
FollowUp Load (0.3ms) SELECT "follow_ups".* FROM "follow_ups" WHERE "follow_ups"."is_complete" = 't'
#<ActiveRecord::Relation [#<FollowUp id: 16, contact_id: 1, owner_id: 1, due_date: "2014-04-23 00:00:00", comment: "Lorem ipsum dolor sit amet, consectetur adipisicin...", is_complete: true, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-17 09:57:00", updated_at: "2014-04-22 14:37:36">, #<FollowUp id: 23, contact_id: 1, owner_id: nil, due_date: "2014-04-22 19:17:01", comment: nil, is_complete: true, created_by_user_id: nil, updated_by_user_id: nil, created_at: "2014-04-22 19:17:01", updated_at: "2014-04-22 19:17:01">]>
[32] pry(main)> FollowUp.where(is_complete: false)
FollowUp Load (0.2ms) SELECT "follow_ups".* FROM "follow_ups" WHERE "follow_ups"."is_complete" = 'f'
#<ActiveRecord::Relation []>
[33] pry(main)> FollowUp.all
FollowUp Load (0.2ms) SELECT "follow_ups".* FROM "follow_ups"
#<ActiveRecord::Relation [#<FollowUp id: 16, contact_id: 1, owner_id: 1, due_date: "2014-04-23 00:00:00", comment: "Lorem ipsum dolor sit amet, consectetur adipisicin...", is_complete: true, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-17 09:57:00", updated_at: "2014-04-22 14:37:36">, #<FollowUp id: 17, contact_id: 1, owner_id: 1, due_date: "2014-04-24 00:00:00", comment: "This ia long comment", is_complete: false, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-17 10:04:13", updated_at: "2014-04-17 10:04:13">, #<FollowUp id: 18, contact_id: 1, owner_id: 1, due_date: "2014-04-24 00:00:00", comment: "This is a comment\r\n", is_complete: false, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-17 10:24:05", updated_at: "2014-04-17 10:24:05">, #<FollowUp id: 19, contact_id: 1, owner_id: 1, due_date: "2014-04-23 00:00:00", comment: "test", is_complete: false, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-22 13:37:40", updated_at: "2014-04-22 13:37:40">, #<FollowUp id: 20, contact_id: 1, owner_id: 1, due_date: "2014-04-23 00:00:00", comment: "test", is_complete: false, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-22 13:37:41", updated_at: "2014-04-22 13:37:41">, #<FollowUp id: 21, contact_id: 1, owner_id: 1, due_date: "2014-04-24 00:00:00", comment: "test", is_complete: false, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-22 13:39:20", updated_at: "2014-04-22 13:39:20">, #<FollowUp id: 22, contact_id: 2, owner_id: 1, due_date: "2014-04-30 00:00:00", comment: "test", is_complete: false, created_by_user_id: 1, updated_by_user_id: 1, created_at: "2014-04-22 13:53:37", updated_at: "2014-04-22 13:53:37">, #<FollowUp id: 23, contact_id: 1, owner_id: nil, due_date: "2014-04-22 19:17:01", comment: nil, is_complete: true, created_by_user_id: nil, updated_by_user_id: nil, created_at: "2014-04-22 19:17:01", updated_at: "2014-04-22 19:17:01">]>
Upvotes: 4
Views: 2769
Reputation: 531
Using sqlite3 in Rails 4.2.5, I find that a boolean field returns ruby true or false when queried from Rails console. However, when queried inside a controller method, it returns a "t" or "f" string. Very weird. So I added a model method:
def fixt?
return self[:fixt] == "t"
end
Schema:
t.boolean "fixt", default: false
Upvotes: 1
Reputation: 2639
In sqlite3, boolean value is not supported. So rails use char 't' and 'f' to represent boolean value true and false. while in other database like mysql, postgresql, the real boolean value true and false is used.
However, this difference is transparent to rails Model. you can just use
FollowUp.where(is_compete: true)
to filter completed followups and
FollowUp.where(is_compete: false)
to get incomplete followups
Upvotes: 5