0

I'm following the book Ruby and MongoDB Web Development, and and trying to follow the examples as much as possible, but for some reasons I'm not able to get it working.

This is what I have so far, models:

app/models/book.rb

class Book
     include Mongoid::Document

     field :title, type: String
     field :publisher, type: String
     field :published_on,  type: Date

     field :votes, type: Array

     belongs_to :author
     has_and_belongs_to_many :categories

     embeds_many :reviews
end

app/models/author.rb

class Author
     include Mongoid::Document

     field :name, type: String

     has_many :books
end

app/models/category.rb

class Category
     include Mongoid::Document

     field :comment, type: String
     field :username, type: String

     has_and_belongs_to_many :books
end

So far so good, then in the rails console

irb(main):001:0> b  = Book.new(title: "Oliver Twist", publisher: "Dover Publications", :published_on => Date.parse("2002-12-30"))
=> #<Book _id: 53c9215c456d655abb000000, title: "Oliver Twist", publisher: "Dover Publications", published_on: 2002-12-30 00:00:00 UTC, votes: nil, author_id: nil, category_ids: nil>

irb(main):002:0> Category.create(name: 'Fiction')
=> #<Category _id: 53c92161456d655abb010000, name: "Fiction", book_ids: nil>

irb(main):004:0* Category.create(name: 'Drama')
=> #<Category _id: 53c92166456d655abb020000, name: "Drama", book_ids: nil>
irb(main):005:0> b.categories << Category.first
=> [#<Category _id: 53c92161456d655abb010000, name: "Fiction", book_ids: [BSON::ObjectId('53c9215c456d655abb000000')]>]

irb(main):006:0> b.categories << Category.last
=> [#<Category _id: 53c92161456d655abb010000, name: "Fiction", book_ids: [BSON::ObjectId('53c9215c456d655abb000000')]>, #<Category _id: 53c92166456d655abb020000, name: "Drama", book_ids: [BSON::ObjectId('53c9215c456d655abb000000')]>]

irb(main):007:0> b.save
=> true
irb(main):008:0> b
=> #<Book _id: 53c9215c456d655abb000000, title: "Oliver Twist", publisher: "Dover Publications", published_on: 2002-12-30 00:00:00 UTC, votes: nil, author_id: nil, category_ids: [BSON::ObjectId('53c92161456d655abb010000'), BSON::ObjectId('53c92166456d655abb020000')]>

irb(main):009:0> Category.first
=> #<Category _id: 53c92161456d655abb010000, name: "Fiction", book_ids: nil>
irb(main):010:0>

The category object does not get updated, what is happening? What I'm doing wrong?. help!

Info: Rails 4, Mongoid 4, Ruby 2.1, MongoDB 2.6

Edit 1:

line embedded_in :book removed unnecessary line from file app/models/category.rb.

yeyo
  • 2,954
  • 2
  • 29
  • 40
  • You cant embed a habtm relation. Add `has_and_belongs_to_many :books` to model Category – Santhosh Jul 18 '14 at 14:47
  • Thanks, but actually that was a line I missed doing the copy&paste from my files. rechecked, and still not working. – yeyo Jul 18 '14 at 14:53
  • What about this `embedded_in :book` – Santhosh Jul 18 '14 at 14:55
  • Yes, that line does not make sense for what it's intended, I have removed that line and tried again, and still is not working. – yeyo Jul 18 '14 at 15:04
  • Strange. btw, did you reload the console, after the model changes? – Santhosh Jul 18 '14 at 15:11
  • Yes I did. I'll do it again just to be 200% sure. – yeyo Jul 18 '14 at 15:16
  • @Santosh I reloaded the console again, and still it's not working :(. Although, records are being saved in mongodb correctly, the only thing that does not work properly is the relationship. – yeyo Jul 18 '14 at 15:24

2 Answers2

3

You should use autosave to support syntax of:

b.categories << Category.first
b.categories << Category.last

to do this, add this to your models

has_and_belongs_to_many :books, autosave: true

has_and_belongs_to_many :categories, autosave: true

to understand what happens, try following code in console without autosave:

b  = Book.new(title: "Oliver Twist", publisher: "Dover Publications", :published_on => Date.parse("2002-12-30"))
c1 = Category.create(name: 'Fiction')
c2 = Category.create(name: 'Drama')
b.categories << c1
b.categories << c2
b.save

c1.changed?
c2.changed?

It change parent object, but not save it automatically.

Ruslan Kyrychuk
  • 366
  • 1
  • 7
  • I did a fast research about this parameter and it turns out it was set as default in previous versions of mongoid but not anymore apparently. Thanks for providing a short and well elaborate answer. – yeyo Jul 22 '14 at 14:03
0

I was finally able to get it to work, although, the way I did it, does not feel quite right to me.

Instead of

b.categories << Category.first
b.categories << Category.last

I used

b.category_ids << Category.first._id
b.category_ids << Category.last._id

Once the document is saved, the Category object gets updated as expected.

I must say, this does not feels quite correct, because many people use the other form, something have to be wrong with either me or the Mongoid gem.

Any further explanation is welcome and may be accepted as the correct answer.

yeyo
  • 2,954
  • 2
  • 29
  • 40