-
Type: Task
-
Resolution: Done
-
Affects Version/s: None
-
Component/s: None
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:
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:
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:
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.