Using question mark character in Rails/ActiveRecord column name
Asked Answered
F

4

43

In keeping with Ruby's idiom of using a question mark in boolean methods (e.g. person.is_smart?), I'd like to do the same for an ActiveRecord field in Rails:

rails generate model Person is_smart?:boolean

I haven't actually run the above statement. I assume that database fields can't have a question mark in them. Will rails deal with this appropriately? Is the best practice to simply leave question marks off of models?

Using Rails 3.2.8

Fitment answered 24/9, 2012 at 5:10 Comment(3)
Why not just call it smart and then add custom accessors so you can say is_smart? when you're talking to an actual Person?Mortar
@Mortar - I guess that makes the most sense since it's not common that you would name a boolean variable with a question mark at the end and we would be treating the above is_smart? as a variable.Fitment
Rails is your friend. See Cdesrosiers' answer.Elaineelam
H
99

Rails will automatically generate the method smart? if there is a field named 'smart'.

Habituate answered 24/9, 2012 at 5:23 Comment(7)
Actually Rails generates ? methods for all columns. They appear to return true only if the value is truthy. So this is a perfect match for booleans.Cytochrome
Actually, Kelvin's comment above is almost right. It returns true if the value is present?, not truthy. So "" returns false, for example.Cylindroid
Is there any documentation for the semantics of the question-mark form?Bibbs
never have been i so wrong. also thought it would just check for present? github.com/rails/rails/blob/master/activerecord/lib/…Noisemaker
...and remember: it is a bad practice in rails to set prefixes like 'is_' or 'has_' in yours methods and columns #37060047Stationery
..and, until is a bad practice, actually it is possible at least in PosgreSQL and MySQL, to use question marks in the columns names which is very painful to use when you write it in a statement.Stationery
Surprisingly, for numeric attributes, the question mark helper checks for 0. If user.level is 0, then user.level? is false but user.level.present? is true!Toitoiboid
M
6

One "gotcha" to be aware of if you happen to use :enum in your model, since this stores the value as an integer. The question mark attr method provided by active record expects to evaluate 0 or 1 as false / true respectively in the database. For example:

class Person
  enum mood: ['happy', 'sad', 'bored']
end

p = Person.new(mood: 'happy') # this would store mood as 0 in db
p.mood? #=> false

p.mood = 'sad' # saves as 1 in db
p.mood? #=> true

p.mood = 'bored' # saves as 2 in db
p.mood? #=> true

to see how this method works, see rails source

Mcnew answered 5/4, 2018 at 10:24 Comment(0)
S
2

From documentation: https://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Attribute+query+methods

In addition to the basic accessors, query methods are also automatically available on the Active Record object. Query methods allow you to test whether an attribute value is present. Additionally, when dealing with numeric values, a query method will return false if the value is zero.

Susannahsusanne answered 30/8, 2022 at 14:46 Comment(0)
L
0

Actually, Im using Rails 4 and I can't call my boolean column without the question mark

pry(main)> User.where(is_validated: false).first.is_validated
  User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."is_validated" = 'f' ORDER BY "users"."id" ASC LIMIT 1
=> nil
[13] pry(main)> User.where(is_validated: false).first.is_validated?
  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."is_validated" = 'f' ORDER BY "users"."id" ASC LIMIT 1
=> false
Lesbian answered 20/1, 2014 at 21:8 Comment(2)
I made an "ask/ answer" post on this topic after this answer, but I kept this as I think this information might be valuable for deciding how to name a bool column as well.Lesbian
its not that you cant call boolean cols without question mark. Its actually showing the actual value you stored in the col. add null: false, default: false clause in the migration.Tishatishri

© 2022 - 2024 — McMap. All rights reserved.