2

I'm trying to do Model Tree Structures with Parent References using Mongoid,
but the parent is set to null.

This is my class:

class Category
  include Mongoid::Document
  field :name, type: String
  belongs_to :parent, :class_name => 'Category'
end

And this is how I create categories:

parent = Category.new(name: "Mobile").save!
child1 = Category.new(name: "Android", parent: parent).save!
child2 = Category.new(name: "iOS", parent: parent).save!

The result:

{ 
    "categories": [
        {
            "_id": "511b84c5cff53e03c6000126",
            "name": "Mobile",
            "parent_id": null,
        },
        {
            "_id": "511b84c5cff53e03c6000128",
            "name": "Android",
            "parent_id": null,
        },
        {
            "_id": "511b84c5cff53e03c6000129",
            "name": "iOS",
            "parent_id": null,
        }
    ]
}

The parent is not even stored in the DB:

{ "name" : "Mobile",  "_id" : "511b84c5cff53e03c6000126" }
{ "name" : "Android", "_id" : "511b84c5cff53e03c6000128" }
{ "name" : "iOS",     "_id" : "511b84c5cff53e03c6000129" }

What am doing wrong?

Thanks!
Roei

Roei
  • 319
  • 4
  • 15

2 Answers2

1

In addition to declaring a belongs_to association you need to declare the opposite has_many association, even if it is on the same class.

class Category
  include Mongoid::Document
  field :name, type: String

  has_many :children,
    class_name: 'Category',
    inverse_of: :parent
  belongs_to :parent,
    class_name: 'Category',
    inverse_of: :children
end

You can the assign a parent or the children through the associations.

parent = Category.create
child1 = Category.create
child2 = Category.create

parent.children << child1
parent.children << child2

The children will then store the reference to the parent.

Thomas Klemm
  • 10,678
  • 1
  • 51
  • 54
  • Are you assigning the parent / childrens through the association? – Thomas Klemm Feb 13 '13 at 21:05
  • @ThomasKlemn I only use 'belongs_to :parent, :class_name => "Category"' to define the relation. I managed to make it work, posted my answer. Thanks for your respond! – Roei Feb 14 '13 at 08:42
0

Eventually it worked when I did the save separately (and not on the same line with the creation).

Before (not works properly):

parent = Category.new(name: "Mobile").save!
child1 = Category.new(name: "Android", parent: parent).save!
child2 = Category.new(name: "iOS", parent: parent).save!

After (works!):

parent = Category.new(name: "Mobile")
child1 = Category.new(name: "Android", parent: parent)
child2 = Category.new(name: "iOS", parent: parent)

parent.save
child1.save
child2.save

The result (as expected):

{ "name" : "Mobile", "_id" : "511b84c5cff53e03c6000126" }
{ "name" : "Android", "parent_id" : "511b84c5cff53e03c6000126", "_id" : "511b84c5cff53e03c6000128" }
{ "name" : "iOS", "parent_id" : "511b84c5cff53e03c6000126", "_id" : "511b84c5cff53e03c6000129" }

Thanks a lot to all responders!

Roei
  • 319
  • 4
  • 15