Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How-to: User has fans

I need users to be able to become fans of other users. How should I design/set this up?

I need to be able to view details of user fans.

For example. I have user: Foo. Foo has 3 fans. I'd like to be able to find the names of Foo's fans. As such:

foo = User.first
foo.name (returns 'Foo')
foo.fans.first.user.name (should return 'bar', since 'bar' is a fan of 'foo')

This is how I have it set up at the moment:

User model:
  embeds_many :fans
  references_many :fans

Fan model:
  embedded_in :user, :inverse_of => :fans
  referenced_in :user

In console, I do:
  User.first.fans.create!(:user => User.first)

and I get: Mongoid::Errors::InvalidCollection: Access to the collection for Fan is not allowed since it is an embedded document, please access a collection from the root document. I think the problem is, because the fan model is embedded in the user model which has a self-reference to the user model as well....

Your thoughts will be much appreciated.

like image 342
Christian Fazzini Avatar asked Nov 08 '10 21:11

Christian Fazzini


People also ask

How do you use fans?

Draw in Cool Air, Expel Hot Air You can cool a room with just one window and one fan. Place a box fan in the window or a pedestal fan within 5 feet of the window. When the air is cooler outside than it is inside, point the air so it blows into the house.

How do I make someone a fan?

Always encourage the behavior you want which is why you should reply to and acknowledge every comment or share you get. Doing so makes the person who did it feel seen, appreciated, and more likely to do it again. It also strengthens their relationship with you which is what it means to be a true fan.

Do fans help cool a room?

A ceiling fan does not actually lower the overall temperature in a room, but it can definitely make a space feel cooler. Ceiling fans primarily work through something called a wind chill effect. Essentially, the moving air across your skin helps to evaporate sweat at a faster rate.

How can I cool my house with fans?

'First, keep your windows, doors and blinds shut during the day to avoid hot sun beating down into your house. Then, during the evening, open your windows and place one fan facing out of your window, so it pushes the heat out,' they advise. 'Use a second fan, placed inwards, to circulate cool air into the room. '


1 Answers

How about a self-referential association:

class User
  include Mongoid::Document
  references_many :fans, 
                  :class_name => 'User', 
                  :stored_as => :array, 
                  :inverse_of => :fan_of

  references_many :fan_of, 
                  :class_name => 'User', 
                  :stored_as => :array, 
                  :inverse_of => :fans
end

# let's say we have users: al, ed, sports_star, movie_star    
sports_star.fans << al
movie_star.fans << al
sports_star.fans << ed
movie_star.fans << ed

movie_star.fans  # => al, ed
al.fan_of        # => sports_star, movie_star

The problem is that you are trying to do relational association using only embedded documents. When you have a Fan embedded inside a User, you can only access the Fan through its parent User. You can't do something like Fan.find(some_id) because there is no collection of Fan records.

Eventually, MongoDB will support virtual collections that will allow you to do this. For now, you have to use relational-type associations. If you want to use embedded documents in this case, you have to create some ugly and inefficient custom methods to search through parent records.

With MongoDB and Mongoid, I have found that you can switch between embedded and relational associations easily. SQL-type relationships and embedded relationships both have their place and can be used together to great effect.

like image 152
bowsersenior Avatar answered Sep 30 '22 12:09

bowsersenior