Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defaulting boolean attributes to true #43

Closed
garyv opened this issue Sep 27, 2012 · 7 comments
Closed

Defaulting boolean attributes to true #43

garyv opened this issue Sep 27, 2012 · 7 comments

Comments

@garyv
Copy link

garyv commented Sep 27, 2012

I was wondering what the best way is to make an Active Record attribute default to true.

This guide recommends setting defaults in the model, not the migration
https://github.com/bbatsov/rails-style-guide#migrations

But this technique fails when defaulting a boolean to true.

def allow_robots
  self[:allow_robots] or true
end

In the code above, allow_robots will always evaluate to true, even if set to false in Active Record. At the very least, there should be a short disclaimer in the guide about the technique not working in this case. But I'd prefer to arrive at a recommended solution.

This variation of the method will get the desired result.

def allow_robots
  !self[:allow_robots].nil? ? self[:allow_robots] : true 
end

At this point, the code's purpose is much less obvious, and defaulting in the migration is starting to look pretty by comparison.

def change
  add_column :settings, :allow_robots, :boolean, :default => true
end

Any thoughts? I feel like there's probably a better way to default true that I just haven't thought of yet.

@garethrees
Copy link

Personally when it comes to booleans I add defaults in the migration to the table itself.

@slamotte
Copy link

As with @garethrees, I set boolean defaults in the table's migration.

@garyv
Copy link
Author

garyv commented Oct 16, 2012

To play devil's advocate for a moment, I just read a blog post suggesting that anytime you store a Boolean in a database, it's a code smell, and you should use a State Machine pattern instead, because it it's easier to maintain or something.

http://railstips.org/blog/archives/2012/10/10/booleans-are-baaaaaaaaaad/

Personally, I've never found State Machines to be intuitive, and I didn't find this argument very convincing. A Boolean state is a much simpler and easier concept to work with. But it's an interesting idea, and it would sidestep the need to set defaults in the database.

@slamotte
Copy link

@garyv thanks for that link. I get what you were trying to add. Personally I hated the article's title (too absolute and polarizing) as well as his example (too contrived, and as you would read in the comments, his problem was really due to a poor design and naming) but regardless, it's an alternative.

I see nothing wrong with using booleans in a table but that's probably because I've been coding long enough to inherently recognize when to use them versus something else. See http://goo.gl/SD8J7

@bbatsov
Copy link
Collaborator

bbatsov commented Oct 17, 2012

Well, setting the defaults in the migrations might be a better idea (especially if several applications are accessing the database).

@slamotte
Copy link

@bbatsov I know it's not "The Rails Way" but I'm a big fan of putting such things as defaults, unique indexes, and declarative referential integrity constraints into databases. If there's the slightest possibility that another app might ever touch the database then I consider this imperative. I've had many heated debates about how this isn't portable or designed right but in my professional opinion you've got to protect your data.

@pirj
Copy link
Member

pirj commented Feb 21, 2021

I believe this was addressed in #275

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants