From 1de308f5b5f7d6ab76ed1e4a6145ba2209f1ef61 Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Thu, 17 Jun 2021 10:35:02 -0500 Subject: [PATCH] Add Add ActiveRecord Error Not Tied To Any Attribute as a Rails til --- README.md | 3 +- ...erecord-error-not-tied-to-any-attribute.md | 61 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 rails/add-activerecord-error-not-tied-to-any-attribute.md diff --git a/README.md b/README.md index 2cd33ba..cb8f5ed 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://tinyletter.com/jbranchaud). -_1131 TILs and counting..._ +_1132 TILs and counting..._ --- @@ -650,6 +650,7 @@ _1131 TILs and counting..._ - [Add A Check Constraint To A Table](rails/add-a-check-constraint-to-a-table.md) - [Add A Foreign Key Reference To A Table](rails/add-a-foreign-key-reference-to-a-table.md) - [Add A Reference Column With An Index](rails/add-a-reference-column-with-an-index.md) +- [Add ActiveRecord Error Not Tied To Any Attribute](rails/add-activerecord-error-not-tied-to-any-attribute.md) - [Add React With Webpacker To A New Rails App](rails/add-react-with-webpacker-to-a-new-rails-app.md) - [Add timestamptz Columns With The Migration DSL](rails/add-timestamptz-columns-with-the-migration-dsl.md) - [Access Secrets In A Rails 5.2 App](rails/access-secrets-in-a-rails-5-2-app.md) diff --git a/rails/add-activerecord-error-not-tied-to-any-attribute.md b/rails/add-activerecord-error-not-tied-to-any-attribute.md new file mode 100644 index 0000000..56ffcec --- /dev/null +++ b/rails/add-activerecord-error-not-tied-to-any-attribute.md @@ -0,0 +1,61 @@ +# Add ActiveRecord Error Not Tied To Any Attribute + +Often the [errors on an ActiveRecord +object](https://api.rubyonrails.org/v6.1.3.2/classes/ActiveModel/Errors.html) +are tied to a specific attribute of that object. For instance, when this +validation is violated + +```ruby +validates :name, presence: true +``` + +Then the error will be tied to `:name`. + +With the +[`ActiveModel::Errors#add`](https://api.rubyonrails.org/v6.1.3.2/classes/ActiveModel/Errors.html#method-i-add) +method, we can write custom validation logic that ties an error to a specific +attribute. + +```ruby +validate :quantity_for_bulk_purchase + +def quantity_for_bulk_purchase + return if purchase_type != :bulk + + if quantity < 12 + errors.add(:quantity, "must be greater than 12 for bulk purchases") + end +end +``` + +Errors don't have to be tied to specific attribute. They can be tied to the +object as a whole. This can be better for validations, like the one above, that +involve multiple attributes. + +```ruby +validate :quantity_for_bulk_purchase + +def quantity_for_bulk_purchase + return if purchase_type != :bulk + + if quantity < 12 + errors.add(:base, "Quantity must be greater than 12 for bulk purchases") + end +end +``` + +By using the `:base` symbol, we are ascribing this error to the object as a +whole. + +``` +> my_object.errors +#=> #[{:error=>"Quantity must be greater than 12 for bulk purchases"}]}, + @messages={:base=>["Quantity must be greater than 12 for bulk purchases"]}> + +> my_object.errors.full_messages +#=> ["Quantity must be greater than 12 for bulk purchases"] +```