How to save embeds_many relation in Mongoid?
mongoid, ruby-on-rails
Solution
I see two possible problems:
- `Hotel.last` is not necessarily `Hotel` 52d68dd47361731d8b000000. You should look at `h.comments` or to be paranoid, `h.reload` and `h.comments`.
- Your associations are confused.
From the fine manual:
Embedded 1-n
One to many relationships where the children are embedded in the parent document are defined using Mongoid's `embeds_many` and `embedded_in` macros.
Defining
The parent document of the relation should use the `embeds_many` macro to indicate it has n number of embedded children, where the document that is embedded uses `embedded_in`.
So your relation should be defined like this:
class Hotel
embeds_many :comments
end
class Comment
embedded_in :hotel
end
You're using `belongs_to: hotel` in `Comment` when you should say `embedded_in :hotel`.
The docs also say that:
Definitions are required on both sides to the relation in order for it to work properly.
and your relation is incorrectly configured on one side so it won't work properly.
Problem
``` class Hotel include Mongoid::Document field :title, type: String embeds_many :comments end class Comment include Mongoid::Document field :text, type: String belongs_to :hotel validates :text, presence: true end h = Hotel.create('hotel') => <#Hotel _id: 52d68dd47361731d8b000000, title: "hotel"> c = Comment.new(text: 'text') => <#Comment _id: 52d68f3d7361731d8b040000, text: "text", hotel_id: nil> h.comments << c => [#<Comment _id: 52d68f3d7361731d8b040000, text: "text", hotel_id: nil>] h.save => true Hotel.last.comments => [] ``` variant 2 ``` h.comments << Comment.new(text: 'new', hotel_id: h.id) => [<#Comment _id: 52d68f3d7361731d8b040000, text: "text", hotel_id: nil>, <#Comment _id: 52d691e17361731d8b050000, text: "new", hotel_id: BSON::ObjectId('52d68dd47361731d8b000000')>] h.save => true Hotel.last.comments => [] ```