necromos
necromos

Reputation: 442

Mongoid nesting with embeds_many two times of one class

Recently I came across issue I cannot resolve (or google it properly). First, here are the files:

#Counter.rb
class Counter
  include Mongoid::Document
  embeds_many :pointing, as: :goodvs, store_as: "goodvs"
  embeds_many :pointing, as: :badvs, store_as: "badvs"
  accepts_nested_attributes_for :pointing

  field :name, type: String
  field :champId, type: Integer
end

#Pointing.rb
class Pointing
  include Mongoid::Document
  belongs_to :counter
  accepts_nested_attributes_for :counter

  field :name, type: String
  field :votes, type: Integer
  field :lane, type: String
end

Description

I want to nest Pointing class in Counter class double to make structure like this:

{
 name: 'sth',
 champId: 1,
 goodvs: [{
           name: 'sthsth'
           votes: 1
           lane: 'top'
         },
         {
           name: 'sthsth2'
           votes: 4
           lane: 'bot'
         }],
 badvs: [{
           name: 'sthsth'
           votes: 1
           lane: 'mid'
         }]
}

Anyone have any solution how to do this? I can make normal structure for nested attributes used once only but I have no clue how to do this properly for this situation.

Upvotes: 1

Views: 395

Answers (1)

Matt
Matt

Reputation: 74909

I have only just started messing around with mongo/mongoid myself but it looks like your class definition is a bit awry. The details are referenced from the Mongoid Relations docs

Use the embedded_in relationship for embeds_many. belongs_to goes with has_many.

class Pointing
  include Mongoid::Document
  embedded_in :counter

  field :name,   type: String
  field :votes,  type: Integer
  field :lane,   type: String
end

If that doesn't fix it... I setup custom relation names slightly differently by using class_name to point back to the actual class. The as: option is documented to be used when the the child document can belong to many parents but I've not used it enough to say if this is an actual difference or just style.

class Counter
  include Mongoid::Document
  embeds_many :goodvs, class_name: "Pointing"
  embeds_many :badvs,  class_name: "Pointing"
  accepts_nested_attributes_for :goodvs, :badvs

  field :name,    type: String
  field :champId, type: Integer
end

Then retrieving the objects I've created with:

Counter.each do |c|
  log 'counter name', c.name, c.id
  log 'goodv', c.goodvs
  log 'goodv first', c.goodvs.first.name, c.goodvs.first.id
  log 'badvs', c.badvs
  log 'badvs first', c.badvs.first.name, c.badvs.first.id
end

Results in:

counter name [sth] [53cfcee66fcb2d2db5000001]
goodv [#<Pointing:0x00000601a395b0>] [#<Pointing:0x00000601a393f8>]
goodv first [mee] [53cfcee66fcb2d2db5000002]
badvs [#<Pointing:0x00000601a37468>] [#<Pointing:0x00000601a372b0>]
badvs first [mee] [53cfcee66fcb2d2db5000002]

So different Pointing object references but both goodvs and badvs contain the same mongo document underneath.

Upvotes: 1

Related Questions