# \[TIP\] Working with columns that end with "?", like "male?"

**URL:** <https://www.ruby-forum.com/t/tip-working-with-columns-that-end-with-like-male/116373>\
**Category:** Rails\
**Created:** [October 4, 2007, 11:24pm UTC](https://www.ruby-forum.com/t/tip-working-with-columns-that-end-with-like-male/116373 "2007-10-04T23:24:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dacbo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b9e5f3/32.png) [@dacbo](https://www.ruby-forum.com/u/dacbo)\
**Post date:** [October 4, 2007, 11:24pm UTC](https://www.ruby-forum.com/t/tip-working-with-columns-that-end-with-like-male/116373/1 "2007-10-04T23:24:13Z")

</div>

I was about to write a really long question asking how to do this, then  
I figured it out. I figured I’d post it in case anyone else runs into  
it.

Lets say you have the following hypothetical table associated with the  
model Attendee:

create\_table :attendees do |t|  
t.column :name, :string  
t.column :first\_time?, :string, :limit =\> 3, :default =\> “no”  
t.column :first\_place?, :boolean, :default =\> false  
end

I altered between using a string and a boolean for the sake of the  
example. Chances are you’d use one or the other.

Now in Erb:

> > a = Attendee.new  
> > =\> #\<Attendee:0x493421c @attributes={“first\_place?”=\>false,  
> > “name”=\>nil, “first\_time?”=\>“no”}, @new\_record=true\>

By convention, ActiveRecord automatically creates a “#{field\_name}?”  
method for each field in your table which returns true or false  
depending on if the field is valued. So if we entered

> > a.methods

We’d see among the results “name” and “name?”, correlating to the name  
column we created.

> > a.name?  
> > =\> false
> 
> > a.name = “CDB”  
> > =\> “CDB”
> 
> > a.name?  
> > =\> true

However, ActiveRecord does not create these methods if your field ends  
in with a “?”! In the list of methods mentioned above we would see only  
“first\_place?” and “first\_time?”, not “first\_place??” nor “first\_time??”  
as I expected. It turns out that ActiveRecord skips this step because it  
sees there is already a method with this name.

> > a.first\_place?  
> > =\> false
> 
> > a.first\_time?  
> > =\> “no”

The first example is misleading as it returns a boolean just as our  
name? method does. This is because the field itself is a Boolean field.  
In fact, there really is no distinction between the name? method that  
ActiveRecord generates and the first\_place? method that correlates to  
our field.

> > a.first\_place?.class  
> > =\> TrueClass
> 
> > a.first\_place?.class.ancestors  
> > =\> [TrueClass, Object, Base64::Deprecated, Base64, Kernel]
> 
> > a.name?.class  
> > =\> TrueClass
> 
> > a.name?.class.ancestors  
> > =\> [TrueClass, Object, Base64::Deprecated, Base64, Kernel]

The tricky part here is that ActiveRecord, for some reason, won’t let  
you set a new value to the first\_time? and first\_place? fields as you  
would normally do.

> > a.first\_place? = true  
> > SyntaxError: compile error  
> > (irb):69: syntax error, unexpected ‘=’, expecting $end  
> > a.first\_place? = true  
> > ^  
> > from (irb):69  
> > from :0
> 
> > a.first\_time? = “yes”  
> > SyntaxError: compile error  
> > (irb):70: syntax error, unexpected ‘=’, expecting $end  
> > a.first\_time? = “yes”  
> > ^  
> > from (irb):70  
> > from :0

So how do we do it? Using an alternate accessor syntax:

> > a[“first\_time?”]  
> > =\> “no”
> 
> > a[“first\_time?”] = “yes”  
> > =\> “yes”
> 
> > a[“first\_place?”]  
> > =\> true
> 
> > a[“first\_place?”] = false  
> > =\> false

I hope that saves someone else a bit of sanity. It had me scratching my  
head for a while. I’m not sure if this is a “bug” or a “feature”, but I  
plan on reporting it just in case.

~ Chris

---

<div class="post-metadata">

**Author:** ![dacbo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b9e5f3/32.png) [@dacbo](https://www.ruby-forum.com/u/dacbo)\
**Post date:** [October 4, 2007, 11:29pm UTC](https://www.ruby-forum.com/t/tip-working-with-columns-that-end-with-like-male/116373/2 "2007-10-04T23:29:58Z")

</div>

Chris B. wrote the following on 04.10.2007 23:24 :

> […]
> 
> > > a.first\_place? = true
> 
> SyntaxError: compile error  
> (irb):69: syntax error, unexpected ‘=’, expecting $end  
> a.first\_place? = true  
> ^  
> from (irb):69  
> from :0

This tries to send “first\_place?=” to the a object.

My guess is that it is Ruby that prevents the ? from being part of the  
method name unless it is the last character.

Nothing ActiveRecord can do about it…

Lionel

---

<div class="post-metadata">

**Author:** ![dacbo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b9e5f3/32.png) [@dacbo](https://www.ruby-forum.com/u/dacbo)\
**Post date:** [October 4, 2007, 11:36pm UTC](https://www.ruby-forum.com/t/tip-working-with-columns-that-end-with-like-male/116373/3 "2007-10-04T23:36:58Z")

</div>

On 10/4/07, Lionel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > from :0
> > 
> > ```
> 
> This tries to send “first\_place?=” to the a object.
> 
> My guess is that it is Ruby that prevents the ? from being part of the  
> method name unless it is the last character.
> 
> Nothing ActiveRecord can do about it…

I think the real question is why on earth would you want to have those  
column names in the first place? If you have to work with a legacy  
db, sure, but I’d never ever ever do that in a migration myself.

And if I did have a legacy db with that schema, I’d just write some  
sensible methods:

def male=(val)  
write\_attribute :male?, val  
end

def male  
read\_attribute :male?  
end

def male?  
!!male  
end

Normal assignment, raw attribute, and predicate…the Rails Way.

Pat

---

<div class="post-metadata">

**Author:** ![dacbo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b9e5f3/32.png) [@dacbo](https://www.ruby-forum.com/u/dacbo)\
**Post date:** [October 5, 2007, 4:01am UTC](https://www.ruby-forum.com/t/tip-working-with-columns-that-end-with-like-male/116373/4 "2007-10-05T04:01:59Z")

</div>

Lionel B. wrote:

> My guess is that it is Ruby that prevents the ? from being part of the  
> method name unless it is the last character.
> 
> Nothing ActiveRecord can do about it…

Good point, Lionel.

Pat M. wrote:

> I think the real question is why on earth would you want to have those  
> column names in the first place? If you have to work with a legacy  
> db, sure, but I’d never ever ever do that in a migration myself.

I didn’t write this to encourage anyone to do so, but in case anyone did  
run into it. I work with an “enterprise helpdesk application” (read:  
bloated piece of crap built on ASP) and the database has a mess of  
fields with special characters like that. So, if you can’t get RoR to  
work with your fields in the dot syntax, you can go at it the  
model[“quoted\_field\_name”] way.

> And if I did have a legacy db with that schema, I’d just write some  
> sensible methods:
> 
> def male=(val)  
> write\_attribute :male?, val  
> end
> 
> def male  
> read\_attribute :male?  
> end
> 
> def male?  
> !!male  
> end

Yeah, that makes sense. I didn’t actually make it to the model code when  
I found this. I was working Erb trying to get some associations to work  
(see my numerous previous topics) and worked it out there before calling  
it quits for the day. You’re right though, you’re better off just  
building better accessor methods if those are the field names that  
you’re stuck with.

Again. I’m not advocating using special field names, however:

1. This _does_ follow the Ruby convention of least surprise  
(first\_place? answers a question and returns a boolean), so it seemed  
natural to try to extend that to the DB (I know better now)

2. ActiveRecord didn’t complain about creating a column named  
:first\_place?, so I would expect it to also handle it properly when  
accessing it later. Or, throw an error or warning when creating the  
field saying that YMMV when using that syntax.

Thanks for weighing in.
