Skip to content

Conversation

HParker
Copy link
Contributor

@HParker HParker commented Jun 13, 2022

This removes the singularize from where which runs on all expand_from_hash keys which might be reflections or column names. This saves a lot of time by avoiding singularizing column names.

Previously in #45163 the singularize was removed entirely. after some reflection, I think it is better to at least give a warning for one release since where is a very popular API and the problems you can run into with incorrect relation could be hard to debug.

Configurable with ActiveRecord::Base.allow_deprecated_singular_assocaitions_name = false / config.active_record.allow_deprecated_singular_assocaitions_name = false

cc: @byroot sorry for the flip flop. I was imaging I didn't know about this change and things just started acting different and felt concerned for that rails user.

@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch from 44dbd92 to 944e083 Compare June 13, 2022 19:42
@@ -79,6 +79,8 @@ def self.configurations

class_attribute :strict_loading_by_default, instance_accessor: false, default: false

class_attribute :strict_association_name, instance_writer: false, default: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could go with a single ActiveRecord.allow_deprecated_singular_assocaition_name (or whatever name you think is good, I didn't think much about it).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprised the rails spellchecker complains about association, but I like allow_deprecated_singular_assocaitions_name enough I went with it. Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it wasn't clear. Aside from the name, I was suggesting to make it an ActiveRecord singleton attribute:

module ActiveRecord
  singleton_class.attr_accessor :allow_deprecated_singular_assocaitions_name
end

This means it's no longer inheritable (but the value here is limited), but you can directly check it where it's needed and don't have to pass it around as much. That should significantly cut down the diff.

@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch 2 times, most recently from 251b57c to e97cc66 Compare June 13, 2022 20:07
@HParker HParker changed the title Add configurable deprecation warning for singular association Add configurable deprecation warning for singular associations Jun 13, 2022
@byroot
Copy link
Member

byroot commented Jun 14, 2022

A couple other things:

  • The setting need to be documented in guides/source/configuring.md
  • We need to add it to load_defaults
  • It need to be added to new_framework_defaults_7_1.rb.tt

@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch from e97cc66 to 147676a Compare June 15, 2022 17:20
@HParker
Copy link
Contributor Author

HParker commented Jun 15, 2022

Thanks @byroot, I have never done configuration variables so I am guessing some of these based on other PRs I was able to find. Please let me know if I got anything wrong.

record within a transaction.

When multiple Active Record instances change the same record within a
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gosh, I gotta disable my "cleanup whitespace" config.

@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch from 147676a to 58937a8 Compare June 15, 2022 17:27
@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch 4 times, most recently from 0c5a5e5 to 90b57b6 Compare June 15, 2022 23:38
@@ -79,6 +79,8 @@ def self.configurations

class_attribute :strict_loading_by_default, instance_accessor: false, default: false

class_attribute :allow_deprecated_singular_associations_name, instance_writer: false, default: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we should make this a global on ::ActiveRecord.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree configuring this per class seems like a really bad idea. Updated thanks!

@@ -44,3 +44,6 @@
# For example, it is possible to create an index for a non existing column.
# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details.
# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true

# Disable deprecated singular associations names
# Rails.application.config.active_record.allow_deprecated_singular_associations_name = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a newline :)

@@ -288,6 +289,12 @@ def load_defaults(target_version)
if respond_to?(:active_record)
active_record.sqlite3_adapter_strict_strings_by_default = true
end
when "7.2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in 7.1 defaults, since 7.1 isn't out yet.

@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch 4 times, most recently from 75444c5 to c947fb6 Compare June 16, 2022 16:11
This removes the singularize from `where` which runs on all `expand_from_hash` keys which might be reflections or column names. This saves a lot of time by avoiding singularizing column names.

Previously in rails#45163 the singularize was removed entirely. after some reflection, I think it is better to at least give a warning for one release since `where` is a very popular API and the problems you can run into with incorrect relation could be hard to debug.

Configurable with `ActiveRecord::Base.allow_deprecated_singular_assocaitions_name = false` / `config.active_record.allow_deprecated_singular_assocaitions_name = false`
@HParker HParker force-pushed the add-deprecation-warning-for-association-names branch from c947fb6 to 3a04c7b Compare June 16, 2022 16:14
@HParker
Copy link
Contributor Author

HParker commented Jun 16, 2022

phew, thanks so much @byroot I know so much more about how configuration variables work 😅

@byroot byroot merged commit 1a37756 into rails:main Jun 16, 2022
@byroot
Copy link
Member

byroot commented Jun 16, 2022

Thanks!

@HParker HParker deleted the add-deprecation-warning-for-association-names branch June 16, 2022 20:10
willnet added a commit to willnet/rails that referenced this pull request Jun 23, 2022
…me [skip ci]

The only time rails#45163 and rails#45344 have an effect is when the hash value passed to `where` is a model object. The current sample code does not change behavior between Rails 7.0 and 7.1
jonathanhefner added a commit to jonathanhefner/rails that referenced this pull request Jun 23, 2022
Follow-up to rails#45344.

This tweaks the description, fleshes out the code example, and fixes the
default value listed for 7.1.
jonathanhefner added a commit to jonathanhefner/rails that referenced this pull request Jun 23, 2022
Follow-up to rails#45344.

When using `config.load_default "7.1"`, the value is `false`, so the
value in `new_framework_defaults_7_1.rb` should be `false` as well.

This commit also adds configuration tests.
jonathanhefner added a commit to jonathanhefner/rails that referenced this pull request Jun 23, 2022
Follow-up to rails#45344.

Currently, when `allow_deprecated_singular_associations_name` is true, a
deprecation warning like the following is displayed:

```console
> Comment.belongs_to :post
> Comment.where(posts: 1).count
DEPRECATION WARNING: In Rails 7.2, referring to singular associations by their plural name will be deprecated.
To continue querying `post` use `posts` instead.
You can get the new more performant behavior now by setting config.active_record.allow_deprecated_singular_associations_name = false
```

The warning advises "use `posts` instead", but the user's code should
actually use `post`, i.e. `Comment.where(post: 1).count`.  The mismatch
is likely due to the level at which the deprecation warning is emitted.
`associated_with?` does indeed expect `table_name` to be `posts`, but
`where` expects `post`.

This commit changes the deprecation warning to avoid advising a specific
usage, but still be explicit about what is wrong:

```console
> Comment.where(posts: 1).count
DEPRECATION WARNING: Referring to a singular association (e.g. `post`) by its plural name (e.g. `posts`) 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.
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants