
Notable ActiveRecord changes in Rails 6 – Part 2
Welcome to the second part of this series about notable changes of ActiveRecord in Rails 6. Part I covered ActiveRecord::Relation#pick
, ActiveRecord::Base.create_or_find_by!
, negative scopes to all enum values, implicit order column configuration. Let’s dive into more methods added in Rails 6.
Raise ActiveModel::MissingAttributeError when update_columns is used with non-existing attribute
Rails 6 now raises ActiveModel::MissingAttributeError
when update_columns
is used with a non-existing
database attribute.
Let’s try updating User with an office_email
field which is not present in the database and you will see the results showing an error.
update_columns
raises ActiveRecord::StatementInvalid
error in earlier version of Rails.
delete_by and destroy_by as ActiveRecord::Relation methods
Rails have find_or_create_by, find_by and similar methods to find first and create if not found a matching record for given parameters. Rails were missing similar feature for deleting/destroying the records.
Before Rails 6, deleting/destroying the record(s) which are matching the given condition is achieved by using multiple methods.
Rails 6 added new ActiveRecord::Relation#delete_by
and ActiveRecord::Relation#destroy_by
methods in ActiveRecord::Relation
which are short-hand for
relation.where(conditions).delete_all
and ActiveRecord::Relation#destroy_by
is short-hand for relation.where(conditions).destroy_all respectively.
You can also pass the multiple attributes in arguments as well.
ActiveRecord::Relation#touch_all
Before understanding touch_all method, let’s recall what existing touch method is. touch is used to update updated_at timestamp by default to the current time, no validation is performed and only the after_touch
, after_commit
, and after_rollback
callbacks are executed.
Rails 6 has added touch_all
on ActiveRecord::Relation
to touch multiple records at once. Before Rails 6, we needed to iterate on all records using an iterator to achieve the same.
Let’s see how we can touch all record in Rails 5
Touch method will return an array of ActiveRecords which are being affected.
Same can be achieved with touch_all in rails 6 easily
touch_all method will return the counts of the ActiveRecords which are being affected instead of an array as for rails 5.
It also takes the custom time or different columns as parameters like below. It’s cool, right?
ActiveModel::Errors#of_kind?
Rails 6 added of_kind
? on ActiveModel::Errors
. It returns true if provided key and message associated with ActiveModel::Errors
object.
The default message is :invalid.
of_kind
? is same as ActiveModel::Errors#added
? but it doesn’t take extra options as a parameter.
ActiveModel::Errors#slice!
Rails 6 added one more method slice
! to ActiveModel::Errors
which makes quite easy to select just a few keys from errors and show or return them. Before Rails 6, we need to convert ActiveModel::Errors
object to a hash before slicing the keys.
Let’s see how it works for Rails 5.2
Below is the example for Rails 6
Thanks for Reading!
If you are interested in learning more about Rails 6, check out following blogs,
Click here for more details…
At BoTree Technologies, we build enterprise applications with our RoR team of 25+ engineers.
We also specialize in RPA, AI, Python, Django, JavaScript and ReactJS.
Consulting is free – let us help you grow!
