Rails now allows associations to be marked as deprecated using deprecated: true

Active Record allows developers to mark associations as deprecated, providing robust reporting mechanisms to identify and eliminate their usage across all environments.

It supports multiple reporting modes and configurable backtraces, making the process of cleaning up or removing associations much safer and more efficient.

Before

We had no built-in way to deprecate associations. Removing an association like this:

has_many :projects

meant deleting projects and hoping CI or manual testing would catch all usage. This is risky in production, especially with incomplete test coverage or mocked associations.

After

Rails introduces deprecated: true for the deprecated associations. With this, Active Record warns every time the association is used.

We can easily mark an association as deprecated by adding the :deprecated option to our has_many, belongs_to, or other association declarations before deleting them.

class Client < ApplicationRecord
  has_many :projects, deprecated: true
end

With this, Active Record will begin reporting any usage of the projects association.

Deprecated warning Deprecated warning

Rails supports three reporting modes—:warn, :raise, and :notify — with the option to enable or disable backtraces as needed.

By default, :warn mode is enabled and backtraces are disabled.

Configuration & Behavior

We can select one of three modes to control how usage is handled:

  1. :warn (default): Logs a warning via the Active Record logger. We can enable clean backtraces to help trace the source.

  2. :raise: Raises an ActiveRecord::DeprecatedAssociationError. Best for test and development environments where we want usage to fail fast. Always includes a clean stack trace.

  3. :notify: Emits an Active Support notification: deprecated_association.active_record. This mode is ideal for integrating with custom monitoring systems like Sentry, New Relic or other observability tools. The payload includes:

    • :reflection — the association object
    • :message — the kind of usage (e.g., post_ids)
    • :location — where it happened
    • :backtrace — optional, for full context

By default, backtraces are disabled. But if usage is indirect or triggered from shared code, enabling backtraces helps:

# config/application.rb

config.active_record.deprecated_associations_options = { mode: :warn, backtrace: true }

Backtraces are clean, filtered using the Rails.backtrace_cleaner, so we get relevant application-level locations without noise.

We can set the behavior for all deprecated associations across our app:

# config/application.rb

config.active_record.deprecated_associations_options = { mode: :notify, backtrace: true }

This ensures consistency across environments and simplifies the rollout of deprecations at scale.

Refer

Need help on your Ruby on Rails or React project?

Join Our Newsletter