3

I am attempting to create a friend network on a site I am making. I am using Mongoid. How do I instantiate friends?

I assume that Users needs to have a relational association with multiple other users. But the following code:

class User
  include Mongoid::Document
  references_many :users, :stored_as=>:array, :inverse_of=> :users
end

tells me that I have an invalid query. What am I doing wrong? Does anybody have any suggestions on how to get what I am looking for?

Ryan
  • 2,102
  • 4
  • 18
  • 23

2 Answers2

3

Apparently, after much research, Mongoid is not currently capable of cyclical assocations, although it is marked as needed fixing and may be fixed in a future version. The current workaround I am using is as follows:

class User
  include Mongoid::Document
  field :friends, :type => Array, :default => []

  def make_friends(friend)
    self.add_friend(friend)
    friend.add_friend(self)
  end

  def friends
    ids = read_attribute :friends
    ids.map { |id|  User.find(id)}
  end

  def is_friends_with? other_user
    ids = read_attribute :friends
    ids.include? other_user.id
  end

protected

  def add_friend(friend)
    current = read_attribute :friends
    current<< friend.id
    write_attribute :friends,current
    save
  end
end
Ryan
  • 2,102
  • 4
  • 18
  • 23
  • Can you post a link to the issue tracking # or discussions you've seen? Is it http://github.com/mongoid/mongoid/issues/labels/wish#issue/140 by chance? – David J. Sep 30 '10 at 03:09
0

The short answer is that you can not. MongoDB does not have the concept of a join table nor does it do joins in general. The Mongoid many-to-many "simulation" is done by storing arrays of foreign keys on each side.

In response to a comment: MongoDB is a document store. It therefore suits situations where "documents" are highly heterogeneous. As you store your Advertisers with a subtree of Campains and Advertisements, you will have to collect the Advertisements for the Advertisers in ruby code. If your data has a very homogeneous form then you could consider using a relational database instead. We often used MySQL for relating objects and then added MongoDB documents to the objects so they would be extensible.

BilalReffas
  • 8,132
  • 4
  • 50
  • 71