Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the tradeoffs of using mongoid's has_and_belongs_to_many with inverse_of

Tags:

mongoid

In the docs it says you can use inverse_of: nil but doesn't really describe the use case: http://mongoid.org/en/mongoid/docs/relations.html#has_and_belongs_to_many

I'm assuming it is useful in the case where one object would have a LOT of the other, so you can just skip that side entirely with inverse_of nil and save some storage space right?

So for example:

class Post
  has_and_belongs_to_many :tags
end

class Tag
  has_and_belongs_to_many :posts, inverse_of: nil
end

A tag might belongs to hundreds or thousands of posts, but a post probably only has 5 tags or so.

So is this a good use case for it? I assume you can still do

tag.posts

etc like normal, and the main trade off is that it changes the query from:

Post.find(tag.post_ids)

into

Post.where(tag_ids: tag.id)

If you have an index on tag_ids it seems like it would still be quite fast. So maybe the best is something like:

class Post
  has_and_belongs_to_many :tags, index: true
end

class Tag
  has_and_belongs_to_many :posts, inverse_of: nil
end

Just want to check my thinking.

like image 362
Brian Armstrong Avatar asked May 30 '12 03:05

Brian Armstrong


1 Answers

You certainly got the use case right but example seems to be reworked upon. Your models should look like this:

class Post
  has_and_belongs_to_many :tags, inverse_of: nil, index: true
end

class Tag
  # you don't want this side as a tag can be related to 1000s of posts
end

You can use the associations from posts but for tags you will have to create queries yourself.

post.tags                    # get tags for a post
Post.where(tag_ids: tag.id)  # find posts for a tag
like image 167
rubish Avatar answered Sep 22 '22 00:09

rubish