I was writing some tests and I ran into something I'm trying to understand.
What is the difference underneath when calling:
.update_attributes(:group_ids, [group1.id, group2.id])
vs
.update_attributes(:groups, [group1, group2])
These 2 models in question:
group.rb
class Group
include Mongoid::Document
has_and_belongs_to_many :users, class_name: "Users", inverse_of: :groups
end
user.rb
class User
include Mongoid::Document
has_and_belongs_to_many :groups, class_name: "Group", inverse_of: :users
end
test code in question:
g1 = create(:group)
u1 = create(:user, groups: [g1])
g1.update_attribute(:users, [u1])
# at this point all the associations look good
u1.update_attribute(:group_ids, [g1.id])
# associations looks good on both sides when i do u1.reload and g1.reload
u1.update_attribute(:groups, [g1])
# g1.reload, this is when g1.users is empty and u1 still has the association
Hope I made sense, thanks
Without schema for the models, your join object, and the actual tests I'm grasping at straws, but based purely on that example my guess would be that the first model contains an attribute that is mapping to an unintended field on your second model, and overwriting it when you pass an entire object, but not when you specify the attribute you want updated. Here's an example: (I'm not assuming you forgot your join table, I'm just using that because its the first thing that comes to mind)
so we create 2 models, each that have a field that maps to user_id
group.create(id:1, user_id:null)
group_user.create(id:1, group_id: 1, user_id:null)
group.update_attributes(user_id: (group_user.id))
So at this point, when you call group.users, it checks for a user with the id of 1, because that's the id of the group_user you just created & passed it, and assuming you have a User with that ID in your database, the test passes.
group_user.update_attributes(group_id: group.id)
In this case the method ONLY updates group_id, so everything still works.
group_user.update_attributes(group_id: group, user_id: group)
In this case you pass an entire object through, and leave it up to the method to decide what fields get updated. My guess is that some attribute from your group model is overwriting the relevant attribute from your user model, causing it to break ONLY when NO user_ids match whatever the new value is.
Or an attribute isn't white listed, or your test is wonky.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With