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

Trouble setting and persisting fields in polymorphic children

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

      Hi, I'm a relative noob wrt Mongoid (polymorphic) relations and having some trouble. I'm not sure if I'm doing something wrong or there's a bug, but there seems to be a workaround. I have a parent Activity which is simplified here for discussion and a child Contact, also simplified.

      class Activity
        include Mongoid::Document
        attr_accessible :contacts
        embeds_many :contacts, as: :contactable, validate: true, class_name: 'Contact'
      end
      
      class Contact
        include Mongoid::Document
        attr_accessor :name, :sites
        field :name, type: String
        field :sites, type: Array
        embedded_in :contactable, polymorphic: true
      end
      

      Note: I added "validate" and "class_name" attributes to the embeds_many clause from other posts I found which don't seem to help/affect my issue.

      In my seeds.rb rake task I generate many activities and want to embed contacts. When I set up a contact using method assignment syntax, it doesn't work as documented. Here a is a new Activity and activity is a hash of mock data:

        
      c = Contact.new
      c.name = CONTACT_NAME
      c.sites = [ activity[:link] ]
      puts "contact #{c.inspect}"
      a.contacts << c
      puts "activity #{a.inspect}"
      a.save!
      
      # results (fail):
      
      contact #<Contact _id: 506861fd05b58e472a000012, _type: nil, salu: nil, name: nil, title: nil, phones: nil, email: nil, sites: nil>
      activity #<Activity _id: 506861fd05b58e472a000013, _type: nil, created_at: nil, updated_at: nil, tags: ["gumps", "macys", "nordstrom"], title: {"en"=>"Shopping in Union Square5"}, type: "a", cat: "shopping", author: "506861f705b58e472a000001", desc: {"en"=>nil}, cost: 0.0, notes: {"en"=>"Take BART"}, dur: 30, views: 0, icon: nil, public: nil, protected: nil, address: "Union Square, San Francisco, CA", icon_filename: nil>
      MOPED: 127.0.0.1:27017 INSERT       database=fixer_development collection=activities documents=[{"_id"=>"506861fd05b58e472a000013", "type"=>"a", "cat"=>"shopping", "cost"=>0.0, "dur"=>30, "views"=>0, "protected"=>nil, "title"=>{"en"=>"Shopping in Union Square5"}, "address"=>"Union Square, San Francisco, CA", "author"=>"506861f705b58e472a000001", "desc"=>{"en"=>nil}, "tags"=>["gumps", "macys", "nordstrom"], "notes"=>{"en"=>"Take BART"}, "coordinates"=>[-122.4074374, 37.7879938], "icon_filename"=>"images", "updated_at"=>2012-09-30 15:15:10 UTC, "created_at"=>2012-09-30 15:15:10 UTC, "contacts"=>[{"_id"=>"506861fd05b58e472a000012"}]}] flags=[] (0.3278ms)
      

      Notice above that the embedded activity being written to Mongo contains a contact with only an _id field. Other variations fail too:

      a.contacts = [ Contact.new(name: CONTACT_NAME, sites: [ activity[:link] ]) ]
      a.save!
      
      # results (fail):
      
      activity #<Activity _id: 506863da05b58e722a00000c, _type: nil, created_at: nil, updated_at: nil, tags: ["gumps", "macys", "nordstrom"], title: {"en"=>"Shopping in Union Square2"}, type: "a", cat: "shopping", author: "506863d605b58e722a000001", desc: {"en"=>nil}, cost: 0.0, notes: {"en"=>"Take BART"}, dur: 30, views: 0, icon: nil, public: nil, protected: nil, address: "Union Square, San Francisco, CA", icon_filename: nil>
      MOPED: 127.0.0.1:27017 INSERT       database=fixer_development collection=activities documents=[{"_id"=>"506863da05b58e722a00000c", "type"=>"a", "cat"=>"shopping", "cost"=>0.0, "dur"=>30, "views"=>0, "protected"=>nil, "title"=>{"en"=>"Shopping in Union Square2"}, "address"=>"Union Square, San Francisco, CA", "author"=>"506863d605b58e722a000001", "desc"=>{"en"=>nil}, "tags"=>["gumps", "macys", "nordstrom"], "notes"=>{"en"=>"Take BART"}, "coordinates"=>[-122.4074374, 37.7879938], "icon_filename"=>"images", "updated_at"=>2012-09-30 15:23:07 UTC, "created_at"=>2012-09-30 15:23:07 UTC, "contacts"=>[{"_id"=>"506863db05b58e722a00000d"}]}] flags=[] (0.3219ms)
      

      And this:

      a.contacts.build(name: CONTACT_NAME, sites: [ activity[:link] ])
      puts "activity #{a.inspect}"
      a.save!
      
      # results (fail):
      
      activity #<Activity _id: 506863da05b58e722a00000c, _type: nil, created_at: nil, updated_at: nil, tags: ["gumps", "macys", "nordstrom"], title: {"en"=>"Shopping in Union Square2"}, type: "a", cat: "shopping", author: "506863d605b58e722a000001", desc: {"en"=>nil}, cost: 0.0, notes: {"en"=>"Take BART"}, dur: 30, views: 0, icon: nil, public: nil, protected: nil, address: "Union Square, San Francisco, CA", icon_filename: nil>
      MOPED: 127.0.0.1:27017 INSERT       database=fixer_development collection=activities documents=[{"_id"=>"506863da05b58e722a00000c", "type"=>"a", "cat"=>"shopping", "cost"=>0.0, "dur"=>30, "views"=>0, "protected"=>nil, "title"=>{"en"=>"Shopping in Union Square2"}, "address"=>"Union Square, San Francisco, CA", "author"=>"506863d605b58e722a000001", "desc"=>{"en"=>nil}, "tags"=>["gumps", "macys", "nordstrom"], "notes"=>{"en"=>"Take BART"}, "coordinates"=>[-122.4074374, 37.7879938], "icon_filename"=>"images", "updated_at"=>2012-09-30 15:23:07 UTC, "created_at"=>2012-09-30 15:23:07 UTC, "contacts"=>[{"_id"=>"506863db05b58e722a00000d"}]}] flags=[] (0.3219ms)
      

      When I avoid the method name approach to setting values and switch to hash-symbol notion it appears to work:

      c = Contact.new
      c[:name] = CONTACT_NAME
      c[:sites] = [ activity[:link] ]
      puts "contact #{c.inspect}"
      a.contacts << c
      puts "activity #{a.inspect}"
      a.save!
      
      # results (success):
      
      contact #<Contact _id: 5068616d05b58e352a000010, _type: nil, salu: nil, name: "Jimmy Bag of Donuts", title: nil, phones: nil, email: nil, sites: ["http://www.unionsquareshop.com"]>
      activity #<Activity _id: 5068616d05b58e352a000011, _type: nil, created_at: nil, updated_at: nil, tags: ["gumps", "macys", "nordstrom"], title: {"en"=>"Shopping in Union Square4"}, type: "a", cat: "shopping", author: "5068616b05b58e352a000005", desc: {"en"=>nil}, cost: 0.0, notes: {"en"=>"Take BART"}, dur: 75, views: 0, icon: nil, public: nil, protected: nil, address: "Union Square, San Francisco, CA", icon_filename: nil>
      MOPED: 127.0.0.1:27017 INSERT       database=fixer_development collection=activities documents=[{"_id"=>"5068616d05b58e352a000011", "type"=>"a", "cat"=>"shopping", "cost"=>0.0, "dur"=>75, "views"=>0, "protected"=>nil, "title"=>{"en"=>"Shopping in Union Square4"}, "address"=>"Union Square, San Francisco, CA", "author"=>"5068616b05b58e352a000005", "desc"=>{"en"=>nil}, "tags"=>["gumps", "macys", "nordstrom"], "notes"=>{"en"=>"Take BART"}, "coordinates"=>[-122.4074374, 37.7879938], "icon_filename"=>"images", "updated_at"=>2012-09-30 15:12:46 UTC, "created_at"=>2012-09-30 15:12:46 UTC, "contacts"=>[{"_id"=>"5068616d05b58e352a000010", "name"=>"Jimmy Bag of Donuts", "sites"=>["http://www.unionsquareshop.com"]}]}] flags=[] (0.3412ms)
      

      Perhaps I'm not properly persisting the child contact? I've never had this problem with non-relational Mongoid classes. Did I miss something obvious?

      I'm also not sure why inspect doesn't show the values I set in the new child contact object, but assuming this has something to do with dirty tracking since it is being persisted in the save call (in the final example that works).

      I'm using the following:

      ruby "1.9.3"
      gem 'rails', '3.2.8'
      gem 'bson', '1.7.0'
      gem 'bson_ext', '1.7.0'
      gem 'mongo', '1.7.0'
      gem 'mongoid', "~> 3.0.0"
      

      UPDATE: I discovered that you said mongo, bson and bson_ext aren't needed. I removed those but this problem persists.

      Thanks for any help. Please let me know if I can provide additional information.

            Assignee:
            durran Durran Jordan
            Reporter:
            teddis teddis
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: