Rails 7.1 adds the raise_on_assign_to_attr_readonly config to config.active_record that is used to raise ActiveRecord::ReadonlyAttributeError error on assignment to attr_readonly attributes. The previous behavior would allow assignment but silently not persist changes to the database.

Configuring config.active_record.raise_on_assign_to_attr_readonly

In a newly created Rails 7.1 application, config.load_defaults 7.1 is set by default in application.rb. The default value of raise_on_assign_to_attr_readonly for config.load_defaults 7.1 is true and for config.load_defaults < 7.1 it is false. To opt-in:

# config/environments/application.rb

config.active_record.raise_on_assign_to_attr_readonly = true

Let's take an example of the following Post model structure:

# app/models/post.rb

class Post < ActiveRecord::Base
  attr_readonly :title
end
  • When config.active_record.raise_on_assign_to_attr_readonly = true

    post = Post.create!(title: "Introducing Ruby on Rails!")
    post.title = "a different title" # raises ActiveRecord::ReadonlyAttributeError
    post.update(title: "a different title") # raises ActiveRecord::ReadonlyAttributeError
    
  • When config.active_record.raise_on_assign_to_attr_readonly = false

    post = Post.create!(title: "Introducing Ruby on Rails!")
    post.title = "a different title" # does not raise any error
    post.update(title: "a different title") # change to title will be ignored
    

References