Pregunta

Estoy tratando de encontrar la manera al formato para mi base de datos para un sitio que estoy trabajando. Aquí están mis modelos:

class User
  include MongoMapper::Document

  // keys here

  many :items
  many :likes
end

class Item
  include MongoMapper::Document

  key :name, String, :required => true

  many :likes
end

class Like
  include MongoMapper::EmbeddedDocument

  key :user_id, String, :required => true
end

Creo que el Like debe ser embebido en alguna parte, pero estoy teniendo un tiempo difícil elegir uno debido a la funcionalidad quisiera salir de ella.

user = User.first
user.likes // should print out all the Items he liked

item = Item.first
item.likes // so I can count how many people like that item

A pesar de que el problema viene cuando se utiliza un EmbeddedDocument, se pierde la find, y otros métodos de votos, y no se puede tenerlo incrustado en ambos modelos. Así que tener sólo en Item, necesitaría para ejecutar este (pero no puede):

item = Item.first
item.likes.find_by_user_id(User.first._id)

será lanzada find_by_user_id método no definido. Así que si yo estaba para insertar este en mi User, todavía no podía hacerlo.

likes = Like.all // will throw undefined `all`

Así que llegó a la conclusing que tal vez hacerlo de esta manera:

class Like
  include MongoMapper::Document

  key :user_id, String, :required => true
  key :item_id, String, :required => true

  belongs_to :user
  belongs_to :item
end

Sin embargo, esto parece como si todavía estoy tratando de hacer las cosas de la manera antigua de MySQL. ¿Podría alguien darme un punto de la forma más probable de este código con MongoMapper?

Gracias de antemano!

¿Fue útil?

Solución

Si es posible modelar esto en MongoMapper depende de si hay datos que necesitan ser almacenados en el modelo Like. Si, como en el ejemplo, no hay ningún dato asociado con el modelo Like, hay una manera. La actualización más reciente a MongoMapper ha añadido soporte para las relaciones de muchos a muchos, a pesar de que todavía está en las primeras etapas.

Se crearía sus modelos como esto:

class User
  include MongoMapper::Document
  key :name, String, :required => true
  key :liked_item_ids, Array
  many :liked_items, :in => :liked_item_ids, :class_name => "Item"
end

class Item
  include MongoMapper::Document
  key :name, String, :required => true
  many :fans, :class_name => "User", :foreign_key => :liked_item_ids
end

A continuación, puede hacer:

>> u = User.new( :name => 'emily' )
>> i = Item.new( :name => 'chocolate' )
>> u.liked_items << i
>> u.save
>> u.liked_items
=> [#<Item name: "chocolate", _id: 4b44cc6c271a466269000001>]

>> i.fans
=> [#<User name: "emily", liked_item_ids: [4b44cc6c271a466269000001], _id: 4b44cc6c271a466269000002>]

Por desgracia, lo que no se puede hacer con esta configuración es añadir una como desde el lado de la relación Item todavía. Sin embargo, hay un problema abierto en GitHub sobre la creación de un inverso correcto para la relación many :in que será utilizado, en este caso, como sigue:

many :fans, :class_name => "User", :source => :liked_items

Por otro lado, si hay información que necesita ser almacenado en el Like, tales como la fecha en que el usuario le gusta el artículo, no hay una manera de modelar la actualidad. La configuración ideal en este caso (sin tener en cuenta lo que está apoyada en MongoMapper en este momento) sería similar a lo que ha incluido en su pregunta. Se necesitaría los tres modelos, con Like incrustado en el modelo User y una relación has_many :through para crear el enlace desde User a Item. Por desgracia, el apoyo para esto en MongoMapper es probablemente bastante lejos.

Si desea fomentar el apoyo para el comportamiento de este tipo en MongoMapper, y pregunta al respecto en la lista de correo o abrir un tema en la MongoMapper github repositorio .

Otros consejos

es posible que desee leer el documento "Insertar vs. Referencia" en la mongodb.org: http://www.mongodb.org/display/DOCS/Schema+Design#SchemaDesign-Embedvs.Reference

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top