The release of Rails 7 took place on April 12th, 2021. Rafael França, Rails Core Team member, had confirmed the release was being targeted for the previous Railsconf.
Hotwire is a collection of components and techniques that use HTML instead of JSON over the wire, as it is usually done in traditional single-page applications.
There are also important additions to ActiveRecord, continuing the valuable work that Eileen M. Uchitelle and the Github team have extracted into the Rails core. Those include, for example, the ability to configure the thread pool for async queries and improvements to the way ActiveRecord connects to multiple database applications that use a custom primary abstract class.
One convenient method I usually use for debugging purposes is the `benchmark` method that is available in views and controllers through ActiveSupport. It simply measures and logs the speed of the code provided in a block.
This small PR allows for using the benchmark method anywhere in your code, such as on your models or services. Anywhere in our code, we can now call:
Which will print the time taken to run lengthy_import_process.
Before Rails 7 and on MySQL, if you had an enum on your model, like this:
If you were to query by status but used an unknown label or had a typo in the value, the find method would wrongly match 0:
Moreover, the behavior was not consistent between adapters: with MySQL, for instance, it would match 0, while for PostgreSQL, it would raise an exception, and for Sqlite3, it would return nil.
After Rails 7, all adapters are returning nil in all such cases.
Rails 6.1 added the strict_loading mode to prevent lazy loading of associations and requires associated records to be eager loaded. It’s a powerful tool to find places where additional queries could be avoided by preloading an association. It’s also a great complement or even replacement for tools such as the Bullet gem, which has been my go-to gem to assist in identifying N+1 queries.
Rails 7 introduces some improvements and convenient settings to configure the strict loading mode.
First, it introduces a mode argument that can be used to enable strict loading for a single record. Until now, enabling strict loading for a single record would raise an error on any lazily loaded association. We can now use n_plus_one_only mode to allow lazily loading associations that are fetched through a single query:
Second, Rails 7 allows us to opt-out of strict-loading mode on a per-record basis when strict loading has been enabled application-wide or on a model level:
Rails 7 adds methods to support file streaming from controllers, and also adds convenience methods to facilitate streaming from ActiveStorage.
Before, you could stream files and on-the-fly generate data through different methods such as manipulating the response headers or through the render method with the :text option, but this commit extracts the existing functionality into a convenient method to be used on any controller:
At the same time ActiveStorage::Streaming has been extracted and leverages the commit above to allow for streaming a blob from cloud storage:
One of the most exciting pieces of news for Rails 7 is the support for attribute encryption. They are regular ActiveRecord attributes that Rails transparently encrypts upon saving and decrypts upon retrieving their values.
You first need to generate a key set to use for encryption and update your Rails credentials by running bin/rails db:encryption:init.
You can then declare any ActiveRecord attributes backed by a column with the same name to be encrypted, as long as they are serializable as strings.
There are many options and features supported by the new encrypted attributes, such as deterministic vs. non-deterministic encryption, advanced key management strategies such as custom key providers or key rotation, and an easy-to-use API to gain more control over this feature.
Finally, ActiveRecord has been extended with several convenience methods that add new functionality and improve the existing API.
The new ActiveRecord::Relation#load_async method, for example, allows for scheduling a query to be performed asynchronously from a thread pool. You can, say, run independent queries in a controller asynchronously:
ActiveRecord::Relation#excluding has been extracted as a convenience method for excluding the specified record or collection of records from the resulting relation. What you would have done before as Post.recent.where.not(id: current_post,id) can be now expressed as Post.recent.excluding(current_post).
Two new methods have been added to FinderMethods : FinderMethods#sole and FinderMethods#find_sole_by. These serve two purposes, as they are to be used when you expect a single row, but also want to assert that only that row matches the condition. If the condition is not met, or it is met by multiple rows, it will throw an error:
A few methods have also been added to conveniently work with associations: build_association and create_association have been added as new constructors on has_one :through associations.
You can also check for the presence or lack of an association with the new where.associated and where.missing methods:
The greatest feature to be released as part of Rails 7 is without a doubt Hotwire since its release as a standalone package has drawn attention not only in the Rails community but also on the ecosystems of other languages.
In this blog post, I highlighted a few interesting features that developers can use frequently in their workflow. Some of these might seem like small additions to the framework, but they illustrate how Rails and the Rails community are always focused on providing the most convenient APIs and build upon the joy that is Ruby as a language.
I suggest you check out the Rails 7 Release notes and Changelogs as these are only a few of the many new features to be released. Also, check this article about Ruby on Rails developers’ salaries. If you’re a developer interested in new challenges, I invite you to visit our careers page.
We’d love to learn more about your project. Contact us below for a free consultation with our CEO.
Projects start at $50,000.