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,

  1. Notable ActiveRecord changes in Rails 6 – Part 1

  2. Introducing jQuery in Rails 6 Using Webpacker


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!