Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-1425

object.relation_id= should clear old relation

    • Type: Icon: Task Task
    • Resolution: Done
    • 2.4.0
    • 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.

            Assignee:
            Unassigned Unassigned
            Reporter:
            gurgeous Adam Doppelt
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: