Search code examples
ruby-on-railsruby-on-rails-4mongoidmongoid4

Mongoid: How to sync both sides of a HABTM relation?


I have two models:

class User
  ...
  has_and_belongs_to_many :groups
  ...
end

class Group
  ...
  has_and_belongs_to_many :users
  ...
end

For some reason the group object doesn't have all the user_ids. Maybe, because I'm using mongoid 4 alpha version.

Group _id: 123, user_ids: [1, 2, 4]
User _id: 3, group_ids: [123, 456]

Although the big issue is why are those documents unsync, for now I need to know how to sync them at this point.

Thanks in advance,

Victor


Solution

  • I found why the documents where unsync. I was setting the group in a NEW user object (not persisted):

    group = Group.last
    user = User.new
    user.groups = [group]
    user.save
    

    According to mongoid docs, it stores the group_ids in the user but not in the group:

    Model#{name}= Set the related documents. If the parent document is persisted, then the child will be saved immediately along with the parent to keep the keys consistent. If setting to nil or [] then the children will be deleted.

    To fix the issue I saved the group after the user is saved: group.save

    Given that I only had one group and that the users are persisted now, I did the following rake task to sync the data:

    users = User.in(group_ids: group.id)
    
    users.each do |user|
      g = user.groups.first
      user.groups = [g]
      user.save
    end