Skip to content

Commit

Permalink
Remove deprecated behavior to support referring to a singular associa…
Browse files Browse the repository at this point in the history
…tion by its plural name
  • Loading branch information
rafaelfranca committed Feb 20, 2024
1 parent 9ef7938 commit 4bf2c4c
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 69 deletions.
8 changes: 8 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,11 @@
* Remove deprecated behavior to support referring to a singular association by its plural name.

*Rafael Mendonça França*

* Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`

*Rafael Mendonça França*

* Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
`ActiveRecord::MigrationContext`.

Expand Down
19 changes: 13 additions & 6 deletions activerecord/lib/active_record.rb
Expand Up @@ -422,12 +422,19 @@ def self.global_executor_concurrency # :nodoc:
singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
self.verify_foreign_keys_for_fixtures = false

##
# :singleton-method: allow_deprecated_singular_associations_name
# If true, Rails will continue allowing plural association names in where clauses on singular associations
# This behavior will be removed in Rails 7.2.
singleton_class.attr_accessor :allow_deprecated_singular_associations_name
self.allow_deprecated_singular_associations_name = true
def self.allow_deprecated_singular_associations_name
ActiveRecord.deprecator.warn <<-WARNING.squish
`Rails.application.config.active_record.allow_deprecated_singular_associations_name`
is deprecated and will be removed in Rails 7.3.
WARNING
end

def self.allow_deprecated_singular_associations_name=(value)
ActiveRecord.deprecator.warn <<-WARNING.squish
`Rails.application.config.active_record.allow_deprecated_singular_associations_name`
is deprecated and will be removed in Rails 7.3.
WARNING
end

singleton_class.attr_accessor :query_transformers
self.query_transformers = []
Expand Down
11 changes: 1 addition & 10 deletions activerecord/lib/active_record/table_metadata.rb
Expand Up @@ -23,16 +23,7 @@ def has_column?(column_name)
end

def associated_with?(table_name)
if reflection = klass&._reflect_on_association(table_name)
reflection
elsif ActiveRecord.allow_deprecated_singular_associations_name && reflection = klass&._reflect_on_association(table_name.singularize)
ActiveRecord.deprecator.warn(<<~MSG)
Referring to a singular association (e.g. `#{reflection.name}`) by its plural name (e.g. `#{reflection.plural_name}`) is deprecated.
To convert this deprecation warning to an error and enable more performant behavior, set config.active_record.allow_deprecated_singular_associations_name = false.
MSG
reflection
end
klass&._reflect_on_association(table_name)
end

def associated_table(table_name)
Expand Down
4 changes: 4 additions & 0 deletions guides/source/7_2_release_notes.md
Expand Up @@ -134,8 +134,12 @@ Please refer to the [Changelog][active-record] for detailed changes.
* Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
`ActiveRecord::MigrationContext`.

* Remove deprecated behavior to support referring to a singular association by its plural name.

### Deprecations

* Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`

### Notable changes

Active Storage
Expand Down
26 changes: 0 additions & 26 deletions guides/source/configuring.md
Expand Up @@ -69,7 +69,6 @@ Below are the default values associated with each target version. In cases of co
- [`config.action_dispatch.default_headers`](#config-action-dispatch-default-headers): `{ "X-Frame-Options" => "SAMEORIGIN", "X-XSS-Protection" => "0", "X-Content-Type-Options" => "nosniff", "X-Permitted-Cross-Domain-Policies" => "none", "Referrer-Policy" => "strict-origin-when-cross-origin" }`
- [`config.action_text.sanitizer_vendor`](#config-action-text-sanitizer-vendor): `Rails::HTML::Sanitizer.best_supported_vendor`
- [`config.action_view.sanitizer_vendor`](#config-action-view-sanitizer-vendor): `Rails::HTML::Sanitizer.best_supported_vendor`
- [`config.active_record.allow_deprecated_singular_associations_name`](#config-active-record-allow-deprecated-singular-associations-name): `false`
- [`config.active_record.before_committed_on_all_records`](#config-active-record-before-committed-on-all-records): `true`
- [`config.active_record.belongs_to_required_validates_foreign_key`](#config-active-record-belongs-to-required-validates-foreign-key): `false`
- [`config.active_record.commit_transaction_on_non_local_return`](#config-active-record-commit-transaction-on-non-local-return): `true`
Expand Down Expand Up @@ -1509,31 +1508,6 @@ For each process, Rails will create one global query executor that uses this man
should be at least `thread_count + global_executor_concurrency + 1`. For example, if your web server has a maximum of 3 threads,
and `global_executor_concurrency` is set to 4, then your pool size should be at least 8.

#### `config.active_record.allow_deprecated_singular_associations_name`

This enables deprecated behavior wherein singular associations can be referred to by their plural name in `where` clauses. Setting this to `false` is more performant.

```ruby
class Comment < ActiveRecord::Base
belongs_to :post
end

Comment.where(post: post_id).count # => 5

# When `allow_deprecated_singular_associations_name` is true:
Comment.where(posts: post_id).count # => 5 (deprecation warning)

# When `allow_deprecated_singular_associations_name` is false:
Comment.where(posts: post_id).count # => error
```

The default value depends on the `config.load_defaults` target version:

| Starting with version | The default value is |
| --------------------- | -------------------- |
| (original) | `true` |
| 7.1 | `false` |

#### `config.active_record.yaml_column_permitted_classes`

Defaults to `[Symbol]`. Allows applications to include additional permitted classes to `safe_load()` on the `ActiveRecord::Coders::YAMLColumn`.
Expand Down
1 change: 0 additions & 1 deletion railties/lib/rails/application/configuration.rb
Expand Up @@ -280,7 +280,6 @@ def load_defaults(target_version)
if respond_to?(:active_record)
active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false
active_record.commit_transaction_on_non_local_return = true
active_record.allow_deprecated_singular_associations_name = false
active_record.sqlite3_adapter_strict_strings_by_default = true
active_record.query_log_tags_format = :sqlcommenter
active_record.raise_on_assign_to_attr_readonly = true
Expand Down
26 changes: 0 additions & 26 deletions railties/test/application/configuration_test.rb
Expand Up @@ -2875,32 +2875,6 @@ def index
assert_equal true, ActiveRecord.verify_foreign_keys_for_fixtures
end

test "ActiveRecord.allow_deprecated_singular_associations_name is false by default for new apps" do
app "development"

assert_equal false, ActiveRecord.allow_deprecated_singular_associations_name
end

test "ActiveRecord.allow_deprecated_singular_associations_name is true by default for upgraded apps" do
remove_from_config '.*config\.load_defaults.*\n'

app "development"

assert_equal true, ActiveRecord.allow_deprecated_singular_associations_name
end

test "ActiveRecord.allow_deprecated_singular_associations_name can be configured via config.active_record.allow_deprecated_singular_associations_name" do
remove_from_config '.*config\.load_defaults.*\n'

app_file "config/initializers/new_framework_defaults_7_1.rb", <<-RUBY
Rails.application.config.active_record.allow_deprecated_singular_associations_name = false
RUBY

app "development"

assert_equal false, ActiveRecord.allow_deprecated_singular_associations_name
end

test "ActiveRecord::Base.run_commit_callbacks_on_first_saved_instances_in_transaction is false by default for new apps" do
app "development"

Expand Down

0 comments on commit 4bf2c4c

Please sign in to comment.