From fc93ecfed4bb16d0ff1658fc0b270180424d0edc Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Mon, 30 Sep 2024 19:50:52 -0500 Subject: [PATCH] Add Validate Column Data With Check Constraints as a Rails TIL --- README.md | 3 +- ...date-column-data-with-check-constraints.md | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 rails/validate-column-data-with-check-constraints.md diff --git a/README.md b/README.md index 80b752b..6f3ab6b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1447 TILs and counting..._ +_1448 TILs and counting..._ --- @@ -986,6 +986,7 @@ _1447 TILs and counting..._ - [Update Column Versus Update Attribute](rails/update-column-versus-update-attribute.md) - [Upgrading Your Manifest For Sprocket's 4](rails/upgrading-your-manifest-for-sprockets-4.md) - [Use IRB And Ruby Flags With Rails Console](rails/use-irb-and-ruby-flags-with-rails-console.md) +- [Validate Column Data With Check Constraints](rails/validate-column-data-with-check-constraints.md) - [Verify And Read A Signed Cookie Value](rails/verify-and-read-a-signed-cookie-value.md) - [Where Am I In The Partial Iteration?](rails/where-am-i-in-the-partial-iteration.md) - [Why Redirect And Return In Controllers](rails/why-redirect-and-return-in-controllers.md) diff --git a/rails/validate-column-data-with-check-constraints.md b/rails/validate-column-data-with-check-constraints.md new file mode 100644 index 0000000..bd2eea8 --- /dev/null +++ b/rails/validate-column-data-with-check-constraints.md @@ -0,0 +1,32 @@ +# Validate Column Data With Check Constraints + +A check constraint is a feature of database systems like PostgreSQL that allows +you to enforce rules about the data that goes in a table's column. As of Rails +6.1, ActiveRecord provides a way to add a check constraint via the DSL. + +In this example, we want to ensure that the value going into the +reading_statuses.status column is one of four values. Nothing else besides +these four values should be allowed. + +```ruby +class AddReadingStatusTable < ActiveRecord::Migration[7.2] + def change + create_table :reading_statuses do |t| + t.references :user, null: false, foreign_key: true + t.references :book, null: false, foreign_key: true + t.string :status, null: false + t.timestamps + end + + add_check_constraint + :reading_statuses, + "status in ('started', 'completed', 'abandoned', 'already_read')", + name: "reading_statuses_valid_status_check" + end +end +``` + +The `#add_check_constraint` method takes the name of the table and a SQL clause +that can evaluate to true or false for a given row. We can optionally include +the name of the check constraint (e.g. {table_name}_{column_name}_check) like +we've done above.