mongoid/mongoid — Issue #1424: object.relation_id= should clear old relation
Author: gurgeous
Created: 2011-11-11 17:39:52+00:00
State: open

I often modify relations by setting the underlying relation_id field. I have to do this all over the place to work with forms in Rails. We're usually talking about hidden form fields that contain the id, populated via autocomplete, drag and drop, etc. Unfortunately setting the relation_id field doesn't flush the old relation proxy.

Test:

```ruby
require "rubygems"
require "mongoid"

Mongoid::Config.from_hash({"database" => "mtest"})

class Library
include Mongoid::Document
field :name
end
class Book
include Mongoid::Document
belongs_to :library
end

one, two = Library.create(:name => "one"), Library.create(:name => "two")

book = Book.new(:library => one)
p book.library.name
book.library_id = two.id
p book.library.name
```

Expected:
"one"
"two"

Actual:
"one"
"one"

The workaround for this problem involves strategically calling reload_relations, like so:

```ruby
book.attributes = params[:book]
book.reload_relations
```

Unfortunately that will also flush out any embedded relations that might've gotten populated by attrbitutes=, so sometimes I have to do something more strenuous:

```ruby
book.attributes = params[:book]
book.attributes.each_pair do |key, value|
if key =~ /^(.*)_id$/
relation = $1
if book.instance_variable_defined?("@#{relation}")
book.remove_instance_variable("@#{relation}")
end
end
end
```

This is especially difficult to deal with inside callbacks. I basically have to defensively clear out relations all over the place.