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!