2010-11-08 4 views
6

Necesito usuarios que puedan ser fanáticos de otros usuarios. ¿Cómo debo diseñar/configurar esto?Cómo hacer: El usuario tiene fans

Necesito poder ver los detalles de los fans de los usuarios.

Por ejemplo. Tengo un usuario: Foo. Foo tiene 3 fans. Me gustaría poder encontrar los nombres de los fanáticos de Foo. Como tal:

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

Ésta es la forma en que he establecido en la actualidad

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) 

y consigo: MongoId :: :: Errores InvalidCollection: Acceso a la colección de ventilador es no permitido, ya que es un documento incrustado, acceda a una colección desde el documento raíz. Creo que el problema es que, debido a que el modelo de ventilador está incrustado en el modelo de usuario que también tiene una autorreferencia al modelo de usuario ...

Le agradecerán mucho sus comentarios.

Respuesta

9

¿Qué tal un auto-referencial asociación:

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 

El problema es que usted está tratando de hacer la asociación relacional utilizando sólo los documentos incrustados. Cuando tiene un Fan incrustado dentro de un User, solo puede tener acceso al Fan a través de su padre User. No puede hacer algo como Fan.find(some_id) porque no hay una colección de registros Fan.

Finalmente, MongoDB admitirá colecciones virtuales que le permitirán hacer esto. Por ahora, debes usar asociaciones de tipo relacional. Si desea utilizar documentos incrustados en este caso, debe crear algunos métodos personalizados desagradables e ineficaces para buscar a través de los registros principales.

Con MongoDB y Mongoid, he encontrado que puede cambiar fácilmente entre asociaciones incrustadas y relacionales. Las relaciones de tipo SQL y las relaciones incrustadas tienen su lugar y se pueden usar juntas para lograr un gran efecto.

+0

User.first.fans << User.last returns Mongo :: OperationFailure: query –

+1

inválido No puede usar 'first' y' last' así, y no puede modificar las asociaciones en su lugar de esa manera. A menudo, 'User.last' devolverá lo mismo que' User.first'! Debe hacer 'u = User.all.entries.first; u2 = User.all.entries.last; u.fans << u2'. Acabo de probar este código nuevamente y funciona para mí. – bowsersenior

+0

¿Y esto me permitirá hacer que los usuarios también se vuelvan fan de ellos mismos? –

Cuestiones relacionadas