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

Embedded fields are duplicated when saving parent

    • Type: Icon: Task Task
    • Resolution: Done
    • 2.5.0
    • Affects Version/s: None
    • Component/s: None

      tl;dr: It only happens to classes that have more than one embeds_many. Only the first key of the hash passed as a parameter to update_attributes will be duplicated.

      (

      {"formats" => "will be duplicated", "authors" => "won't be duplicated"}

      )
      (

      {"authors" => "will be duplicated", "formats" => "won't be duplicated"}

      )

      Long version:

      # -*- encoding : utf-8 -*-
      module Catalogue
        class MagazineIssue
          include Mongoid::Document
          include Mongoid::Timestamps
          include Mongoid::Serialization
      
          embeds_many :formats, class_name: Catalogue::Author.name
          embeds_many :authors, class_name: Catalogue::Author.name
        end
      end
      
          21:   put '/:id' do
          22:     magazine_issue = Catalogue::MagazineIssue.find(params[:id])
       => 23:     require 'pry'; binding.pry
          24:     magazine_issue.update_attributes parse_body(parse_json) 
          25:   end
          26: end
      
      [3] pry(#<Catalogue::Controllers::MagazineIssue>)> body = parse_body(parse_json)
      => {"formats"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}],
       "authors"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}]}
      [4] pry(#<Catalogue::Controllers::MagazineIssue>)> formats = body.delete "formats" (only one embeds_many field being updated at this time)
      => [{"name"=>"Josh Powel",
        "brazilian"=>false,
        "biographical_note"=>nil,
        "twitter"=>nil,
        "facebook"=>nil,
        "blog"=>nil,
        "photo"=>nil,
        "type"=>"Author"},
       {"name"=>"Josh Powel",
        "brazilian"=>false,
        "biographical_note"=>nil,
        "twitter"=>nil,
        "facebook"=>nil,
        "blog"=>nil,
        "photo"=>nil,
        "type"=>"Author"}]
      [7] pry(#<Catalogue::Controllers::MagazineIssue>)> magazine_issue.update_attributes body
      => true
      [8] pry(#<Catalogue::Controllers::MagazineIssue>)> Catalogue::MagazineIssue.find(params[:id]).formats.count
      => 2
      [9] pry(#<Catalogue::Controllers::MagazineIssue>)> Catalogue::MagazineIssue.find(params[:id]).authors.count
      => 2 (no problems when updating one field at a time)
      [10] pry(#<Catalogue::Controllers::MagazineIssue>)> body
      => {"authors"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}]}
      [11] pry(#<Catalogue::Controllers::MagazineIssue>)> formats
      => [{"name"=>"Josh Powel",
        "brazilian"=>false,
        "biographical_note"=>nil,
        "twitter"=>nil,
        "facebook"=>nil,
        "blog"=>nil,
        "photo"=>nil,
        "type"=>"Author"},
       {"name"=>"Josh Powel",
        "brazilian"=>false,
        "biographical_note"=>nil,
        "twitter"=>nil,
        "facebook"=>nil,
        "blog"=>nil,
        "photo"=>nil,
        "type"=>"Author"}]
      [12] pry(#<Catalogue::Controllers::MagazineIssue>)> body["formats"] = formats
      => [{"name"=>"Josh Powel",
        "brazilian"=>false,
        "biographical_note"=>nil,
        "twitter"=>nil,
        "facebook"=>nil,
        "blog"=>nil,
        "photo"=>nil,
        "type"=>"Author"},
       {"name"=>"Josh Powel",
        "brazilian"=>false,
        "biographical_note"=>nil,
        "twitter"=>nil,
        "facebook"=>nil,
        "blog"=>nil,
        "photo"=>nil,
        "type"=>"Author"}]
      [13] pry(#<Catalogue::Controllers::MagazineIssue>)> body (two embeds_many fields being updated at this time)
      => {"authors"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}],
       "formats"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}]}
      [14] pry(#<Catalogue::Controllers::MagazineIssue>)> magazine_issue.update_attributes body
      => true
      [15] pry(#<Catalogue::Controllers::MagazineIssue>)> Catalogue::MagazineIssue.find(params[:id]).authors.count
      => 4
      [16] pry(#<Catalogue::Controllers::MagazineIssue>)> Catalogue::MagazineIssue.find(params[:id]).formats.count
      => 2
      
      Demonstration that the order of the parameter makes difference:
      
      [1] pry(#<Catalogue::Controllers::MagazineIssue>)> body = parse_body(parse_json)
      => {"formats"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}],
       "authors"=>
        [{"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"},
         {"name"=>"Josh Powel",
          "brazilian"=>false,
          "biographical_note"=>nil,
          "twitter"=>nil,
          "facebook"=>nil,
          "blog"=>nil,
          "photo"=>nil,
          "type"=>"Author"}]}
      [2] pry(#<Catalogue::Controllers::MagazineIssue>)> magazine_issue.update_attributes body
      => true
      [3] pry(#<Catalogue::Controllers::MagazineIssue>)> Catalogue::MagazineIssue.find(params[:id]).authors.count
      => 2
      [4] pry(#<Catalogue::Controllers::MagazineIssue>)> Catalogue::MagazineIssue.find(params[:id]).formats.count
      => 4
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            bpinto bpinto
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: