Moving document between collections in Mongo (via Mongoid)
I'm building a card game (basic 52 card deck of playing cards 4 suits * 13 ranks), and I've decided on MongoDB for this project.
My basic model is: --> Game --> Deck --> Cards --> Players --> Hand (as Deck) --> Cards --> Final (as Deck) --> Cards --> Closing (as Deck) --> Cards
Ideally I'd like to shift cards off the game's deck into the various piles that Players have.
However, doing something like: game.players[0].hand.cards.push(game.deck.cards.shift(1))
doesn't work, the card in question isn't removed from the game's deck (because #delete is never called), and it isn't added to the player's hand (from my limited understanding, Mongoid will only add new objects to an embedded collection.)
So to move a card from one pile to another, I basically have to do this: game = Game.first player = game.players.first
card = game.deck.cards.shift
copy = Card.new(card.card_id) #read,create
player.hand.cards << copy
if player.save!
card.delete #delete
game.save
end
Not earth shatteringly difficult, but I'm basically doing a READ, a DESTROY and a CREATE, to basically emulate what could be a very simple UPDATE.
Is there something I'm missing? Is this a limitation of the Mongoid ODM? Is moving documents between collections a huge no-no?
I'm very open开发者_开发知识库 to suggestions about the model, as I have no idea if embedded documents are even a good fit for this type of problem.
Below is the corresponding boiler plate
class Deck
include Mongoid::Document
field :is_deck, :type => Boolean
embedded_in :game
embedded_in :player
embeds_many :cards
end
class Card
include PlayingCards
include Mongoid::Document
embedded_in :deck
field :card_id, :type => Integer
field :idx, :type => Integer #used to maintain shuffled order since mongodb is insertion order
field :rank, :type => String
field :suit, :type => String
end
class Game
include Mongoid::Document
embeds_one :deck #deck players draw from
embeds_many :players
field :current_player, type: Integer
field :num_players, type: Integer
end
class Player
include Mongoid::Document
embedded_in :game
embeds_one :hand, class_name: "Deck"
embeds_one :closing, class_name: "Deck"
embeds_one :final, class_name: "Deck"
end
Thanks in advance!
You should read about difference between embedded and referenced associations.
for ex.
class Parent
embeds_one :child
end
class Child
embedded_in :parent
end
Object child = Child.new cant't be created It can be only access via Parent and created on that lavel or destroy.
So you need think what you want to achive if you want to move achieve.
embedded_in :game
embedded_in :player
So this already wrong. That should be referenced by (if I correctly understood idea). You cant embed 1 object in 2 documents. This not for embedded is used to.
http://mongoid.org/docs/relations/embedded.html http://mongoid.org/docs/relations/referenced.html
Read this.
精彩评论