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 => [] ```

Original source