Built in (boolean)? method

When creating a boolean attribute in ActiveRecord, you get a ? method for free. Sadly, it’s returning false for a true value. Does anyone know what might be going on?

ruby-1.8.7-p302 > m.for_charity?

=> false

ruby-1.8.7-p302 > m.for_charity

=> true

ruby-1.8.7-p302 >

Thx in advance


The actual representation of any attribute type in Rails will depend on the underlying DBMS as the mapping changes from platform to platform. But if we assume we’re talking about SQLite as an example, it uses a SQLite boolean which is actually stored as 0 for FALSE or 1 for TRUE, and both of these are considered “trueish” values by Ruby.

i know about the storage issue (or at least I thought I did) but what I am saying is that the returned values are different between the attribute for_charity and for_charity?

Surely that has nothing to do with how the values are stored? I sent the output form console in my original email to show that.


It works ok for me using mysql, could you post the section of
schema.rb for that table?

I have never used the for_charity? syntax though. There does not seem
much point when it is a boolean. Is that syntax documented somewhere?


Sorry, I misunderstood the original message. Ran similar tests in my local environment with same Ruby / Rails, and wasn’t able to get a similar outcome. Is there anything in your model that could be overriding the dynamically created accessor?

I have never used the for_charity? syntax though. There does not seem
much point when it is a boolean.

I've been using it ever since reading dire warnings in the first
edition of Agile Web Development with Rails:

"[To represent true or false, some databases] use integer columns,
where 0 is false and 1 is true... The problem is that in Ruby the
number 0 and the string "f" are both interpreted as true values in
conditions... To query a column as a boolean value in a condition, you
must append a question mark to the column's name"

I must confess I was surprised to learn (prompted by this thread) that
Active Record has a feature that emulates boolean columns for
databases that don't support them natively, so you do get a literal
true or false value out of the attribute, instead of a 1 or 0. And was
even more surprised to learn that this feature was added quite a long
time ago (version 1-ish, AFAICT).

But warnings like the above are still passed on (and in fact are still
present in the current edition of AWDWR). I and others clearly missed
the memo.

Is that syntax documented somewhere?

It's currently implemented in ActiveRecord::AttributeMethods::Query,
and mentioned in the preamble doc for ActiveRecord::Base (but only as
a way of checking for the presence of attributes, not as a way to
typecast fake boolean columns).

The MySQL connection adaptor's boolean emulation behaviour is
configurable via
ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans, which
is documented.


What a great list, ask some questions and get excellent answers. Thanks Chris.


I am soooooooooooo sorry for wasting everyone’s time. I don’t have words to say how stupid I am. I know we’re not allowed to swear on this list.

Colin, to answer your earlier question about whether I had a method overriding one of the attribute calls and the answer is … I obviously checked before posting whether I had a for_charity? method and the answer was yes, I did, but it was commented out. It was old.

The real full answer to your question is … yes I did, but not hard enough. There was another f*%$^ing for_charity? method off screen that I was still using. Of course, pressing n in vim more than once was too much hard work for me.

I can’t believe what an idiot I am.

You know, I could write about how stressed I am and how under pressure I am to get this thing out of the door (which is all true), but I won’t. Because idiot is idiot!!

At least you learnt a bit form Chris so it wasn’t all bad :wink:

Thx for your time everyone and please don’t give up on me. I really am not really all that stupid and one day, I might have a sensible question!!


Just for the record I can't claim the prize for that call, it was Chris Kottom.