views:

458

answers:

3

I'm sure this is a very simple question, but I'm just a newbie so...

I have a model, Game, which has_many :piles. Pile, in turn, has_many :cards. I'm able to populate the Piles and Cards at creation of the Game, so my code at present looks something like:

class Game < ActiveRecord::Base
  has_many :piles

  def after_create
    1.upto(4) do |num|
      Pile.new("game_id" => id, "contents" => "c_type_#{num}")
    end
  end
end

class Pile < ActiveRecord::Base
  has_many :cards
  belongs_to :game

  def after_create
    1.upto(10) do |num|
      Card.new("pile_id" => id, "value" => num)
    end
  end
end

class Card < ActiveRecord::Base
  belongs_to :pile
end

Now this is all very well, but it feels wrong to be passing "game_id" => id when ActiveRecord knows that game_id is the foreign key and should refer to the parent game. But if I leave it off, the foreign key ends up unset. Is there a better way to do this?

(For a bonus, probably simpler, question; suppose Game also has_one :monkey. How best do I create the monkey from within the Game model?)

+6  A: 

Instead of:

Pile.new("game_id" => id, "contents" => "c_type_#{num}")

try:

piles.create("contents" => "c_type_#{num}")

It tries saving the created pile straight away. Or, if you really need that no saving takes place (which is the case with create), you can do:

new_pile = piles.build("contents" => "c_type_#{num}")

Similar for the Pile class and its cards.

As for has_one :monkey, you can do the following (from within a method of Game):

create_monkey("some_attr" => "some_value")
Sergei Kozlov
+2  A: 

Your Game object's piles association collection will have build and create methods provided by Active Record (the create method also saves the associated object assuming it passes validation).

You should be able to do something like this:

def after_create
  1.upto(4) do |num|
    piles.create(:contents => "c_type_#{num}")
  end
end
John Topley
A: 

In addition to what the others have said, you should consider viewing this week's railscast - which deals with inherited resources in Rails 2.3, specifically in views.

Part 2 should appear next monday (2010-01-18)

egarcia