Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubocop/rails-style-guide
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: armandmgt/rails-style-guide
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Jan 14, 2025

  1. Copy the full SHA
    712c833 View commit details
Showing with 15 additions and 4 deletions.
  1. +15 −4 README.adoc
19 changes: 15 additions & 4 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1167,19 +1167,30 @@ And you'll have to consider the fact that most non-trivial apps share a database

=== 3-state Boolean [[three-state-boolean]]

With SQL databases, if a boolean column is not given a default value, it will have three possible values: `true`, `false` and `NULL`.
With SQL databases, if a boolean column is nullable, it will have three possible values: `true`, `false` and `NULL`.
Boolean operators https://en.wikipedia.org/wiki/Three-valued_logic[work in unexpected ways] with `NULL`.

For example in SQL queries, `true AND NULL` is `NULL` (not false), `true AND NULL OR false` is `NULL` (not false). This can make SQL queries return unexpected results.

To avoid such situations, boolean columns should always have a default value and a `NOT NULL` constraint.
To avoid such situations, boolean columns should always have a `NOT NULL` constraint.

Note that when adding a boolean column to an existing table, a default value should be put in place. Otherwise the `NOT NULL` constraint will break for existing rows.

[source,ruby]
----
# bad - boolean without a default value
# bad - boolean column on a new table without a `NOT NULL` constraint
create_table :users do |t|
t.boolean :active
end
# bad - adding a boolean without a `NOT NULL` constraint or without a default value
add_column :users, :active, :boolean
add_column :users, :active, :boolean, null: false
# good - boolean with a default value (`false` or `true`) and with restricted `NULL`
# good - boolean with a `NOT NULL` constraint, and a default value (`false` or `true`) for existing tables
create_table :users do |t|
t.boolean :active, null: false
end
add_column :users, :active, :boolean, default: true, null: false
add_column :users, :admin, :boolean, default: false, null: false
----