views:

430

answers:

2

Hello, i am currently trying to learn Ruby On Rails as i am a long-time PHP developer so i am building my own community like page. I have came pritty far and have made the user models and suchs using MySQL. But then i heard of MongoDB and looked in to it a little bit more and i find it kinda nice.

So i have set it up and i am using mongomapper for the connection between rails and MongoDB. And i am now using it for the News page on the site. I also have a profile page for every User which includes their own guestbook so other users can come to their profile and write a little message to them.

My thought now is to change the User models from using MySQL to start using MongoDB. I can start by showing how the models for each User is set up.

The user model:

class User < ActiveRecord::Base
            has_one :guestbook, :class_name => "User::Guestbook"

The Guestbook model model:

class User::Guestbook < ActiveRecord::Base
  belongs_to :user
  has_many :posts, :class_name => "User::Guestbook::Posts", :foreign_key => "user_id"

And then the Guestbook posts model:

class User::Guestbook::Posts < ActiveRecord::Base
  belongs_to :guestbook, :class_name => "User::Guestbook"

I have divided it like this for my own convenience but now when i am going to try to migrate to MongoDB i dont know how to make the tables. I would like to have one table for each user and in that table a "column" for all the guestbook entries since MongoDB can have a EmbeddedDocument. I would like to do this so i just have one Table for each user and not like now when i have three tables just to be able to have a guestbook.

So my thought is to have it like this:

The user model:

class User
  include MongoMapper::Document
  one :guestbook, :class_name => "User::Guestbook"

The Guestbook model model:

class User::Guestbook
  include MongoMapper::EmbeddedDocument
  belongs_to :user
  many :posts, :class_name => "User::Guestbook::Posts", :foreign_key => "user_id"

And then the Guestbook posts model:

class User::Guestbook::Posts
  include MongoMapper::EmbeddedDocument
  belongs_to :guestbook, :class_name => "User::Guestbook"

But then i can think of one problem.. That when i just want to fetch the user information like a nickname and a birthdate then it will have to fetch all the users guestbook posts. And if each user has like a thousand posts in the guestbook it will get really much to fetch for the system. Or am i wrong? Do you think i should do it any other way?

Thanks in advance and sorry if i am hard to understand but i am not so educated in the english language :)

+1  A: 

If you are going to have thousands of guestbook entries then it would probably be a good idea to make that a separate collection (for exactly the reason that you've stated).

Mike Buckbee
so i shouldnt use it in a EmbededDocument? i should create a seperate table for the posts?
Micke
Can't i just use :select ? or does it even fetch all the guestbok posts? maybe it only fetches the posts when using the post Model?
Micke
I view embedded documents as conceptually similar to de-normalizing a database: it's a way of avoiding a "join" between two separate tables or collections.
Mike Buckbee
+1  A: 

No you don't have to fetch all the guestbook entries if you fetch a user, this is the mongo query for and MongoMapper shouldn't work so much differently (For myself, I'm using Mongoid):

db.users.find({_id: '21314'}, {guestbook: 0})
                // instead of {guestbook: 1} which would return only the guestbook

Something to be aware of, MongoDB still has a limit of 4mb for a single document but that should be tens of thousands of guestbook entries. You might as well push older ones into a sort of archive.

Thomas R. Koll
could you maybe write me the mongomapper query as i can't find it out myself? thanks!
Micke
Yeah, documentation, the dark side of mongomapper. The best advice is to read the test cases of mongomapper closely and here's the one you are interested in:http://github.com/jnunemaker/mongomapper/blob/master/test/unit/test_query.rb#L292-294`User.find('12341', :select => {:guestbook => 0})`
Thomas R. Koll
Yeah, i think mongomapper is great but the lack of documentation really brings it down. I have looked a little on Mongoid now when you mentioned it. And it really looks great. Would you recommend me to switch to mongomapper instead?
Micke
I switched there myself after my patches for more documentation weren't accepted.
Thomas R. Koll
Yeah, but how the hell can i generate a mongoid.yml file in rails 2.3?I just generate a new app when using `rails generate mongoid:config`
Micke