Tim Brunsmo
Tim Brunsmo

Reputation: 601

Relations with mongoid, what should i use?

I'm using Ruby on Rails 3.1 with mongoid and trying to set up som rather simple relations between posts, comments, users and tags. I'm very new to mongodb, and no-sql in general so I'm a bit confused.

What I am trying to accomplish is this: Users, posts and comments should be able to have multiple tags. Tags should have name, type and a count of how many times it has been used. I need to be able to get all available tags so that users kan choose from them. And the other way around, be able to retrieve tags from users, posts and comments.

I've read a lot about it, and still can't seem to figure out which approach I should take. Should I use referencial or embedded relationships? I've looked at a couple of gems but no-one seems to work as i described above.

Sidenote: I am going to use Tire for my search-function later on.

Upvotes: 1

Views: 641

Answers (1)

Tyler Brock
Tyler Brock

Reputation: 30136

Cool, welcome to MongoDB! This is hard to get right and depends on your application but I'll try and give you some pointers based on what you've written and what I think will work best.

This isn't always the case but the general theory is that if an object is always manipulated and viewed in context of another you should embed it inside that object. This is probably the case with comments and posts in your application. Therefore you may want to embed comments inside posts.

However, because you use the tag object in multiple contexts I would make it its own collection like this:

class Tag
    include Mongoid::Document
    field :tag, type: String
    field :type, type: String
    field :count, type: Integer
end

Let's run down your requirements and build the models.

Tags should have name, type and a count of how many times it has been used.

Done via above code for Tag class.

Users, posts and comments should be able to have multiple tags.

Ok so let's give each of these classes a "tags" field that has an array of tag IDs, this would be a referential relationship.

class User
    include Mongoid::Document
    field :first_name, type: String
    field :last_name, type: String
    field :email, type: String
    field :tags, type: Array
end

Also here we will embed comments inside of the posts along with having the array of tag IDs like we do for Users.

class Post
    include Mongoid::Document
    field :subject, type: String
    field :body, type: String
    field :tags, type: Array
    embeds_many :comments
end

class Comment
    include Mongoid::Document
    field :name, type: String
    field :type, type: String
    field :count, type: Integer
    embedded_in :post
end

Make sense? There is some more info here on modeling these sorts of relationships in Rails but using mongomapper instead of mongoid (so don't pay attention to the syntax but pay attention to the ideas presented)

Upvotes: 8

Related Questions