Improve your Rails app’s performance, flexibility, and data integrity with these three useful features.
ActiveRecord Excluding
The .excluding
method of Active Record 5.0 is a new powerful tool added in Rails 7, that allows you to exclude specific columns from a query result.
This method can be used in a variety of situations, such as:
- To return only the essential fields from a record
- To return a more compact dataset for display or export
- To improve the performance of a query by excluding columns that are not needed for the result
- To reduce the amount of data that needs to be processed, such as when calculating an aggregation
Let’s assume you have a list of users and you want to send an email to your entire database, except for this list.
Usually, you would do something like:
1
User.where.not(id: users.map(&:id)
The .excluding
is more concise and easier to read. It is also more efficient.
1
User.all.excluding(users)
ActiveRecord Strict Loading
It is a feature introduced in Rails 6.1 that allows you to force associations to be loaded eagerly.
Eager loading is a technique that loads all of an object’s associations at the time it is loaded. This can improve the performance of applications by avoiding N + 1 queries.
ActiveRecord Strict Loading works by enabling the strict_loading
mode for an association. When the strict_loading
mode is enabled, Active Record will raise an exception if the association is loaded lazily.
1
2
3
class Post < ApplicationRecord
has_many :comments, strict_loading: true
end
1
2
3
4
5
post = Post.first
post.comments
# => ActiveRecord::StrictLoadingViolationError
# "Post" is marked as strict_loading. The Post association named ":comments" cannot be lazily loaded.
1
2
3
4
5
6
7
8
post = Post.includes(:comments).first
# => Post Load (0.3ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT ? [["LIMIT", 1]]
# => Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? [["post_id", 1]]
#=> <Post:0x00000001054af780 id: 1>
post.comments
#=> [<Comment:0x00000001054aed80 id: 1, project_id: 1, body: "Great Post">]
ActiveRecord Strict Loading can be useful for applications that need to guarantee that all associations are loaded eagerly. However, it is important to note that strict loading can reduce the flexibility of your code.
Here are some examples of how ActiveRecord Strict Loading can be used:
- To improve the performance of applications that make many N + 1 queries.
- To ensure that all associations are available for all methods of an object.
- To avoid lazy association errors in applications that are running in production environments.
Generated Columns
Generated columns are a feature introduced in Postgres 12 that is now supported by Rails 7. It allows you to create columns of data that are calculated dynamically.
To create a generated column in a migration, use the add_column
method with the :virtual
argument.
There are two different types of generated columns: Virtual (computed at read) Stored (computed and cached at write – create/update)
For example, the following code creates a generated column called full_name
that calculates the full name of a user
:
1
2
3
4
5
6
7
8
9
class AddNameVirtualColumnToUsers < ActiveRecord::Migration [7.0]
def change
add_column :users, :full_name, :virtual,
type: string,
as: "first_name || ' ' || last_name",
stored: true
end
end
end
This code creates a generated column called full_name
that stores the full name of a user. The value of the column is calculated using the expression first_name || ' ' || last_name
.
The value of the generated column can be stored in memory or in the database. To store the value of the generated column in memory, use the :stored
argument with the value false
. To store the value of the generated column in the database, use the :stored
argument with the value true
.