-
-
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
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 <[email protected]>
…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
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'.