This Week in Rails

November 25, 2022

Disable enum methods generation, a concurrency fix and more!

Hi there,
This is Greg, bringing you the latest changes in Rails.

Make sure that concurrent map usage is thread-safe
This pull request changes the way a cache miss is handled. It makes it thread-safe and ensures that it's not overwritten in the middle of execution.

Autoload ActiveModel::ValidationError
This pull request adds the missing autoload call for the ValidationError in Active Model.

Execute the before_committed! callbacks on the most recent copy of the record
Before this change, only the early copy of the same record (different object ids, but pointing to the same record in the database) was used to execute the callback, but it didn't have the touch_later information.

Ensure file_fixture_path is set even when Active Record is not present
When generating an app with --skip-active-record, the file_fixture helper was failing, because file_fixture_path is only defined if ActiveRecord::Base. This pull request loads the test helper even when Active Record is not present.

Add X-Forwarded-To addresses to recipients
This pull request enhances Mail::Message#recipients to include the address that an email was forwarded to.

Allow hash-like model in FormBuilder#fields and FormBuilder#fields_for
This pull request changes the way ActionView::Helpers::FormBuilder#fields_for interprets parameters. Before deciding that the record_object parameter is in fact the fields_options parameter, Rails now checks if this fields_options has not been explicitly provided.

Add a build persistence method
This pull request adds a build method to ActiveRecord::Persistence,  which builds an object (or objects) and returns either the built object or objects. Here are a few examples of usage:
# Build a single new object
User.build(first_name: 'Jamie')

# Build an Array of new objects
User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])

# Build a single object and pass it into a block to set other attributes.
User.build(first_name: 'Jamie') do |u|
  u.is_admin = false
end

Allow setting YAML serialization options on a per-attribute basis
This pull request adds functionality to allow setting YAML serialization options on a per-attribute basis - along with the current application-wide setting.

Add support for HTML attributes of optgroups to select helper
With this change, choices of select can optionally contain HTML attributes as the last element of the child arrays when using grouped/nested collections:
<%= form.select :foo, [["North America", [["United States","US"],["Canada","CA"]], { disabled: "disabled" }]] %>
# => <select><optgroup label="North America" disabled="disabled"><option value="US">United States</option><option value="CA">Canada</option></optgroup></select>

Allow resetting singular associations
has_one and belongs_to associations now define a reset_association method on the owner model (where "association" is the name of the association). This method unloads the cached associate record, if any, and causes the next access to query it from the database. There is an example of usage in the pull request description.

Avoid validating belongs_to association if it has not changed
With this change, Rails avoids validating belongs_to association if it has not changed. Previously, when updating a record, Active Record performed an extra query to check for the presence of belongs_to associations (if the presence is configured to be mandatory), even if that attribute hasn't changed.
Currently, only belongs_to-related columns are checked for presence. It is possible to have orphaned records with this approach. To avoid this problem, you need to use a foreign key.
This behavior can be controlled by configuration:
 config.active_record.belongs_to_required_validates_foreign_key = false
and will be disabled by default with `load_defaults 7.1`.

Restore Action Cable Redis pub/sub listener on connection failure
The Redis pub/sub adapter now automatically reconnects when Redis connection is lost.

Add option to disable all methods that ActiveRecord.enum generates
This pull request adds the instance_methods, option to the enum definition. When it is set to false, Active Record will not generate the instance methods it does by default.

This is a long issue and even being this long, it doesn't cover everything from past week. You can see the whole list of changes here.
We had 24 contributors to Rails this past week!

Happy Thanksgiving if you celebrate it and see you next week!