Ruby on Rails: Creating child objects
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
. 开发者_StackOverflowHow best do I create the monkey from within the Game model?)
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")
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
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)
精彩评论