Reputation: 12805
Let's say I have 'users' and 'favorites', in a many-to-many relationship.
To add a favorite to a user, I could do something like this:
user.favorites << my_new_favorite unless user.favorites.include?(my_new_favorite)
The problem is that this is not how I would do it in Mongo. This is fetching all the user's favorites (could be thousands), only to check if one of them exists.
Any ideas on how to optimize that line of code to be more performant?
Upvotes: 0
Views: 1301
Reputation: 12805
I ended up creating my own link() function, based on @rubish answer.
Add this to initializers/mongoid.rb:
module Mongoid
module Document
def link(entity)
add_to_set((entity.class.name.demodulize.downcase!.to_s + '_ids').to_sym, entity.id)
save!() unless persisted?
entity.add_to_set((self.class.name.demodulize.downcase!.to_s + '_ids').to_sym, id)
end
end
end
And then just link() your many-to-many related entities, eg:
my_new_favorite = Favorite.find_or_initialize_by(:field => 'value')
user.link(my_new_favorite)
Improvements are welcome, I started using ruby last month.
Upvotes: 0
Reputation: 10907
You can use mongoid's add_to_set method here.
user.add_to_set(:favorite_ids, my_new_favorite.id)
Upvotes: 2
Reputation: 25029
I don't really think the check is necessary at all - Mongoid will automatically handle removing dupes from associations, so just append the favorite as you normally would.
Upvotes: 0