Rails introduces disallowed deprecations in ActiveSupport


As we upgrade our application’s Rails version, we often come across deprecation warnings.

For example:

> user.update_attributes(name: 'New name')
DEPRECATION WARNING: update_attributes is deprecated and will be removed from
Rails 6.1 (please, use update instead)
(0.1ms)  begin transaction
User Update (2.7ms)  UPDATE "users" SET "name" = ?, "updated_at" = ? WHERE
"users"."id" = ? [["title", "New name"], ["updated_at", "2019-05-11 11:32:48.075786"],
 ["id", 1]]
(1.1ms)  commit transaction
=> true

In the above case, we remove these deprecation warnings by replacing update_attributes to update.

But, when developing new features after it, we might use end up using deprecated update_attributes again. We might ignore these deprecation warnings and on next Rails upgrade we will encounter new issues.

To avoid the above case, Rails has introduced disallowed deprecations in ActiveSupport. Once we have removed deprecations from codebase, we configure these deprecations as disallowed. If a disallowed deprecation is used, it will be treated as a failure and raise an exception in development or test environment. In production, we log the deprecations as error.

We can configure the disallowed_warnings in our config file as below:

ActiveSupport::Deprecation.disallowed_warnings = [
  "update_attributes",
   :update_attributes,
  /(update_attributes)!?/,
]

Configuration rules as seen above are defined in an array. Array elements can be String, Symbol or Regexp. In each case we try to match the array element as a substring or regex match in our warning message.

Disallowed configuration can be set to raise exception for all deprecation warning by using :all symbol as below:

ActiveSupport::Deprecation.disallowed_warnings = :all

We can set the behavior for disallowed messages to either :raise, :log or :notify.

ActiveSupport::Deprecation.disallowed_behavior = [:log]

By default, it is set to :raise in development and test environment and :log in production environment.

We can temporarily re-allow disallowed deprecation using the .allow method.

ActiveSupport::Deprecation.allow do
  User.code_that_calls_update_attributes_method
end

We can also pass an array of string, symbol or regular expression elements to this method.

ActiveSupport::Deprecation.allow [:update_attributes, "update_attributes!"] do
  User.code_that_calls_update_attributes_method
end

The .allow method call also be called conditionally as shown below

ActiveSupport::Deprecation.allow [:update_attributes], if: Rails.env.production? do
  User.code_that_calls_update_attributes_method
end