Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two 1 - N relations in Mongoid (Rails)

The scenario is:

How can an Account give ratings to another account? This results in two lists on the Account. Those who I have rated and those who have rated me. (my_ratings and ratings_given)

This boils down to:

How can multiple 1 - N relationsips to the same entity work in Mongoid?

In Mongoid's Docs it says you can use has_many and belongs_to to link the entities together.

I currently have this on Account

  has_many :ratings, :as => "my_ratings"
  has_many :ratings, :as => "ratings_given"

and this on Ratings:

 belongs_to :user, :as => 'Rater'
 belongs_to :user, :as => 'Ratie'

The docs don't cover this case, so I thought you would have to differentiate between the two with an :as parameter.

Is this even remoting correct?

like image 812
Arron S Avatar asked Jun 18 '11 06:06

Arron S


People also ask

Can I use Mongoid with rails?

Rails Mongoid was built and targeted towards Rails applications, even though it will work in any environment. However if you are using Rails consult the next two sections on how Mongoid hooks into a Rails application. For a sample Rails application and examples of domain modeling, please see the Mongoid demo application, Echo.

How to define one to many relationships in Mongoid?

One to many relationships where the children are stored in a separate collection from the parent document are defined using Mongoid's has_many and belongs_to macros. This exhibits similar behavior to Active Record.

What is the relationship between documents in MongoDB?

Relationships in MongoDB represent how various documents are logically related to each other. Relationships can be modeled via Embedded and Referenced approaches. Such relationships can be either 1:1, 1:N, N:1 or N:N. Let us consider the case of storing addresses for users. So, one user can have multiple addresses making this a 1:N relationship.

Where can I find the source code for the Mongoid app?

The application will be similar to the blog application described in the Ruby on Rails Getting Started guide, however using Mongoid instead of ActiveRecord as the database adapter. The complete source code for this application can be found in the mongoid-demo GitHub repository. This guide assumes basic familiarity with Ruby on Rails.


1 Answers

You can achieve what you want using the class_name and inverse_of options:

class Account
  include Mongoid::Document
  field :name
  has_many :ratings_given, :class_name => 'Ratings', :inverse_of => :rater
  has_many :my_ratings, :class_name => 'Ratings', :inverse_of => :ratee
end

class Ratings
  include Mongoid::Document
  field :name
  belongs_to :rater, :class_name => 'Account', :inverse_of => :ratings_given
  belongs_to :ratee, :class_name => 'Account', :inverse_of => :my_ratings
end

The documentation has changed since I was last working with it so I wasn't sure whether this is still the recommended approach. Looks like it doesn't mention these options on the 1-many referenced page. But if you take a look at the general page on relations they are covered there.

In any case you need to explicitly link ratings_given/rater and my_ratings/ratee associations when there are two associations to the same class, otherwise mongoid has no way to know which of the two potential inverses to pick.

like image 86
Steve Avatar answered Oct 24 '22 14:10

Steve