Как смоделировать и создать собственную колоду карт в рельсах? - PullRequest
1 голос
/ 07 марта 2009

Я пытаюсь смоделировать карточную игру для изучения Rails. Это отличается от стандартной колоды игральных карт тем, что в колоде может быть несколько копий карты. Я сталкиваюсь с проблемами при попытке инициализировать колоду. До сих пор у меня есть базовая модель карты с различными атрибутами (например, copy_in_deck), но без ассоциаций. Модель DeckCard, представляющая карты в колоде (это связано с наличием нескольких карт одной и той же карты в колоде):

class DeckCard < ActiveRecord::Base
  belongs_to :card
  belongs_to :deck
end

Эти колоды в конечном итоге будут иметь атрибуты, отражающие положение; например, в стопке сброса, в колоде розыгрыша и т. д.

Модель колоды с

belongs_to :game
has_many :deck_cards

Я пытаюсь инициализировать колоду, и у меня возникают различные проблемы. Я пробую следующее в колоде

def initialize
  @cards = Card.find(:all)
  @cards.each do |card|
    # eventually another loop here on copies_in_deck
      @deck_cards.build(card)
  end
end

Когда я делаю Deck.new, я получаю сообщение об ошибке на nil.build. Почему @deck_cards nil?

Я использую InstantRails2, у которого есть rails 2.0.2. Я нашел эту статью о создании нескольких моделей за одно действие, поэтому я попытался использовать Deck.create! вместо этого, и получил ошибку о неправильном количестве аргументов.

Есть предложения?

Ответы [ 3 ]

1 голос
/ 07 марта 2009
class Deck < ActiveRecord::Base
  belongs_to :game
  has_many :deck_cards

  # To create new: Deck.new.build_deck
  def build_deck
    Card.find(:all).each do |card|
      self.deck_cards << DeckCard.new(:card => card)
    end
  end
end
1 голос
/ 07 марта 2009

подклассы ActiveRecord не должны определять метод инициализации, поскольку ActiveRecord позаботится об этом за вас.

Звучит так, будто вы хотите одну запись на карту. А модель DeckCard может одновременно хранить более одной колоды карт.

Re: Почему @deck_cards nil? Потому что вы его нигде не установили.

@ deck_cards - переменная экземпляра. Вы пытаетесь вызвать метод build для него, но вы ничего не установили. Вы должны вызывать сборку (или создание или новый метод) для класса DeckCard.

Если вы хотите создать и сохранить карту в модели DeckCard:
DeckCard.create (карточка) # not @ deck_cards.build (карточка)

Larry

0 голосов
/ 07 марта 2009

Не используйте #initialize для объектов, которые наследуются от ActiveRecord :: Base. Это сломает всякую внутреннюю магию Rails. Вместо этого используйте обратный вызов #after_initialize, описанный здесь: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

Обратите внимание, что after_initialize вызывается после поиска, а также для вновь созданных объектов, поэтому вы захотите обернуть код инициализации, чтобы убедиться, что объект не был сохранен ранее (используйте #new_record?):

def after_initialize
  if new_record?
    # initialize deck_cards here.
  end
end

В прошлом я использовал этот альтернативный подход с более приятным синтаксисом, но имейте в виду, что он не срабатывает, пока вы не попытаетесь сохранить или проверить запись.

before_validation :build_default_associations, :if => :new_record?

def build_default_associations
  # initialize default associations here.
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...