So with that said, I'm learning how to do some things with MongoDB & Mongoid that I had run into some trouble with. I'm planning to do a few posts coming up that will be just knowledge dumps and would hopefully be useful to some folks that may be running into the same problems as I did.
One of the things I wanted to do was provide the ability to have threaded comments in the system. Due to the schemaless design of MongoDB, this should be relatively easy. Some of you may have seen this gist then you have encountered the older way to handle this kind of situation where a Comment object would be able to be embedded within a Comment object.
Let's start with a plain Comment Mongoid document class in Ruby.
require 'mongoid' class Comment include Mongoid::Document include Mongoid::Timestamps field :title, type: String field :body, type: String validates_presence_of :body attr_accessible :title, :body endNow, Mongoid 2.0.x now supports recursive models instead of using the syntax seen in the gist. This just requires one line to be added to the class:
recursively_embeds_manyAdding in this will now provide your Comment Mongoid model with two new methods: parent_comment & child_comments. These are dynamically created based on the name of your class (parent_# & child_#s) and they allow you to traverse the hierarchy.
The Comment model would now look something like:
require 'mongoid' class Comment include Mongoid::Document include Mongoid::Timestamps field :title, type: String field :body, type: String #comment.parent_comment # Gets the parent. #comment.child_comments # Gets the children. recursively_embeds_many validates_presence_of :body attr_accessible :title, :body end
That's it! Not so bad once I read the upgrade page that this was changed.
Have you seen the 'mongoid-ancestry' Gem?
ReplyDeleteNo, I haven't checked that out before. For what I'm doing, the built-in recursive embedding will probably be fine, however thanks for the heads up as I have a different app I can use that gem on.
ReplyDeletehi eric, i tried the code in my rails 3 app for the User model but it doesn't work. the functionality that i require is let a user follow other users. i m using mongodb 2.2.1 and mongoid gem.
ReplyDeleteirb(main):073:0* User.count
=> 4
irb(main):074:0> u = User.last
=> #
irb(main):075:0> u.child_users
=> []
irb(main):076:0> u.child_users < [#]
irb(main):077:0> u.save
=> true
irb(main):078:0> u = User.last
=> #
irb(main):079:0> u.child_users
=> []
irb(main):080:0>
Prasad, sorry for the late reply but that's definitely not going to work with embeds_many. This is because when adding a model to an existing model, the model added must not have been persisted yet. This is because the new model is literally embedded in the document of the parent model.
ReplyDeleteYou would need to do something along the lines of references_many where the id of users following are stored as an array in the parent user model.
Nice blog provide much information if you want to look for some beautiful
ReplyDeleteevening gowns you can visit the centraldress a unqiue store for women wear