Reputation: 319
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
Upvotes: 2
Views: 700
Reputation: 319
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!
Upvotes: 0
Reputation: 10856
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.
Upvotes: 1