-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
BugFix: '<attribute>' and '<attribute>_id' conflict. #1709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BugFix: '<attribute>' and '<attribute>_id' conflict. #1709
Conversation
|
I had expected this problem to be much more difficult to resolve, but can't find anything wrong with your code, good job 🙌 When trying to understand the conflict ignored attributes - that as far as I've seen only applies to transient ones - makes the processing hard to understand. I think you managed well to make this easier to grasp. |
| end | ||
|
|
||
| def hash_instance_methods_to_respond_to | ||
| @attribute_list.names + override_names + @build_class.instance_methods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use attribute_names? side note: just lost a number of hours on the bug this PR will solve 😢 , thank you for working to fix it! 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
832cfe7 to
3dde8e6
Compare
- AttributeAssigner refactored to ignore a
matching attribute alias, if it also
matches the name of another attribute.
- Tests added for attribute assignment.
- Gemfile update from rebasing on main.
3dde8e6 to
d6fe17d
Compare
d6fe17d to
44eace5
Compare
neilvcarvalho
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @CodeMeister - I took the liberty of improving the acceptance specs related to aliases, and added the edge case test you implemented.
Thank you so much for the great solution. It was very elegant.
…tbot#1767) * Ensure association overrides take precedence over trait-defined foreign keys In 6.5.5, changes related to PR thoughtbot#1709 introduced an unintended behavior where a trait-defined `*_id` could take precedence over an explicit association override. This could lead to inconsistency between the association and its foreign key. * Update `AttributeAssigner#aliased_attribute?` to prioritize associations When an association override is provided (e.g., `user: user_instance`), the corresponding trait-defined foreign key is ignored, keeping the object graph consistent with Rails/ActiveRecord expectations. The fix preserves the intent of PR thoughtbot#1709 regarding attribute/attribute_id conflicts. * Add regression specs - Association override wins over trait-defined foreign key - Trait-defined foreign key applies when no association override is present - Multiple foreign-key traits remain supported Example: Before (6.5.5): FactoryBot.build(:post, :with_user_id_999, user: user).user_id # => 999 After (this change; consistent with 6.5.4): FactoryBot.build(:post, :with_user_id_999, user: user).user_id # => user.id Related: thoughtbot#1709, thoughtbot#1767 --------- Co-authored-by: Jin Oketani <b1506231@planet.kanazawa-it.ac.jp>
…tbot#1767) * Ensure association overrides take precedence over trait-defined foreign keys In 6.5.5, changes related to PR thoughtbot#1709 introduced an unintended behavior where a trait-defined `*_id` could take precedence over an explicit association override. This could lead to inconsistency between the association and its foreign key. * Update `AttributeAssigner#aliased_attribute?` to prioritize associations When an association override is provided (e.g., `user: user_instance`), the corresponding trait-defined foreign key is ignored, keeping the object graph consistent with Rails/ActiveRecord expectations. The fix preserves the intent of PR thoughtbot#1709 regarding attribute/attribute_id conflicts. * Add regression specs - Association override wins over trait-defined foreign key - Trait-defined foreign key applies when no association override is present - Multiple foreign-key traits remain supported Example: Before (6.5.5): FactoryBot.build(:post, :with_user_id_999, user: user).user_id # => 999 After (this change; consistent with 6.5.4): FactoryBot.build(:post, :with_user_id_999, user: user).user_id # => user.id Related: thoughtbot#1709, thoughtbot#1767
* Respect association overrides over trait-defined foreign keys (#1767) * Ensure association overrides take precedence over trait-defined foreign keys In 6.5.5, changes related to PR #1709 introduced an unintended behavior where a trait-defined `*_id` could take precedence over an explicit association override. This could lead to inconsistency between the association and its foreign key. * Update `AttributeAssigner#aliased_attribute?` to prioritize associations When an association override is provided (e.g., `user: user_instance`), the corresponding trait-defined foreign key is ignored, keeping the object graph consistent with Rails/ActiveRecord expectations. The fix preserves the intent of PR #1709 regarding attribute/attribute_id conflicts. * Add regression specs - Association override wins over trait-defined foreign key - Trait-defined foreign key applies when no association override is present - Multiple foreign-key traits remain supported Example: Before (6.5.5): FactoryBot.build(:post, :with_user_id_999, user: user).user_id # => 999 After (this change; consistent with 6.5.4): FactoryBot.build(:post, :with_user_id_999, user: user).user_id # => user.id Related: #1709, #1767 * Add clarifying comment for association override precedence Adds a comment explaining why association overrides take precedence over trait-defined foreign keys in AttributeAssigner#aliased_attribute?. * fix: addresses regression in attribute assignment factory_bot v6.5.5 included a patch which worked around the previous limitaion of not being able to assign both <attribute> and <attribute>_id as independent attributes. The change introduced regressions into how attributes are assigned. This commit fixes regressions involving declared attributes which are aliases of overrides where an association is involved. It fixes behavior where the attributes are not assigned in the expected manner as well as fixes an instance where an extra erroneous associated object is created. * fix: correct specs for Rails 6.1 --------- Co-authored-by: Valerie Burzynski <valerie.burzynski@thoughtbot.com>
Fixes: #1680
Fixes: #1142
Addresses: #1708
When a factory has both <attribute> and <attribute>_id, each one is considered an alias for the other
and are not assigned correctly.
This request eliminates this issue by checking if the override is an existing attribute name, before matching against an alias.
It works for any recorded aliases, not just '_id'.