I did some digging around and there does seem to be some confusing behaviour with Mongoid associations, but I found a method that works.
Setup
Given the following:
irb(main):001:0> user1 = User.create!
irb(main):002:0> user2 = User.create!
irb(main):003:0>
irb(main):004:0> device = user1.deleted_devices.create!
Test with #merge!
user2.merge!
doesn't work, and the association remains empty:
irb(main):006:0> user2.deleted_devices.merge!(user1.deleted_devices)
irb(main):007:0> user2.deleted_devices
=> []
and device still belongs to user1
irb(main):008:0> device.user == user2
=> false
irb(main):009:0> device.user == user1
=> true
Test with #update
Let's explore a bit. At first glance, it seems like #update
might work:
irb(main):006:1* user1.deleted_devices.each do |dd|
irb(main):007:1* dd.update(user: user2)
irb(main):008:0> end
irb(main):009:0> device.user == user2
=> true
irb(main):010:0> device.user == user1
=> false
but user1
's association still contains device
(and confusingly, so does user2
's), so destroying it would destroy device
too:
irb(main):011:0> user2.deleted_devices
=> [#<DeletedDevice _id: 63833fb82efba308139e9d38, created_at: 2022-11-27 10:45:12.538566 UTC, updated_at: 2022-11-27 10:45:19.352898 UTC, user_id: BSON::ObjectId('63833fb82efba308139e9d37')>]
irb(main):012:0> user1.deleted_devices
=> [#<DeletedDevice _id: 63833fb82efba308139e9d38, created_at: 2022-11-27 10:45:12.538566 UTC, updated_at: 2022-11-27 10:45:19.352898 UTC, user_id: BSON::ObjectId('63833fb82efba308139e9d37')>]
irb(main):013:0> user1.destroy
=> true
irb(main):014:0> device.reload
/Users/pmv/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/mongoid-8.0.2/lib/mongoid/reloadable.rb:27:in `reload': (Mongoid::Errors::DocumentNotFound)
message:
Document(s) not found for class DeletedDevice with id(s) 63833fb82efba308139e9d38.
Doing user1.destroyed_devices.clear
before deleting it might do the trick, and that doesn't fire callbacks, but it's far from ideal.
Success with <<
This however appears to work for me:
irb(main):006:0> user2.deleted_devices << user1.deleted_devices
=> [#<DeletedDevice _id: 638340dd2efba3084a1b36af, created_at: 2022-11-27 10:50:05.692256 UTC, updated_at: 2022-11-27 10:50:12.892345 UTC, user_id: BSON::ObjectId('638340dd2efba3084a1b36ae')>]
irb(main):007:0> user2.deleted_devices.count
=> 1
irb(main):008:0> user2.deleted_devices
=> [#<DeletedDevice _id: 638340dd2efba3084a1b36af, created_at: 2022-11-27 10:50:05.692256 UTC, updated_at: 2022-11-27 10:50:12.892345 UTC, user_id: BSON::ObjectId('638340dd2efba3084a1b36ae')>]
device
now belongs to user2
:
irb(main):009:0> device.user == user2
=> true
irb(main):010:0> device.user == user1
=> false
user1
's association is now empty, and destroying it doesn't destroy device
:
irb(main):011:0> user1.deleted_devices
=> []
irb(main):012:0> user1.destroy
=> true
irb(main):013:0> device.reload
=> #<DeletedDevice _id: 638340dd2efba3084a1b36af, created_at: 2022-11-27 10:50:05.692 UTC, updated_at: 2022-11-27 10:50:12.892 UTC, user_id: BSON::ObjectId('638340dd2efba3084a1b36ae')>
Relevant versions
Gemfile.lock
mongoid (8.0.2)
rails (7.0.4)
$ brew info mongodb-community
==> mongodb/brew/mongodb-community: stable 6.0.1