Ruby on Rails:创建子对象

时间:2010-01-10 19:25:07

标签: ruby-on-rails ruby foreign-keys parent-child

我确信这是一个非常简单的问题,但我只是一个新手......

我有一个模型,游戏,has_many :piles。反过来,桩has_many :cards。我可以在创建游戏时填充Piles和Cards,所以我的代码目前看起来像:

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

现在这一切都很好,但是当ActiveRecord 知道时,传递"game_id" => id感觉错误,即game_id是外键并且应该引用父游戏。但如果我把它关掉,那么外键最终会被取消。有更好的方法吗?

(对于奖金,可能更简单,问题;假设游戏也has_one :monkey。我如何最好地在游戏模型中创建猴子?)

3 个答案:

答案 0 :(得分:14)

而不是:

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

尝试:

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

尝试直接保存创建的桩。或者,如果确实需要不进行保存(create就是这种情况),您可以这样做:

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

类似于桩类及其卡片。

对于has_one :monkey,您可以执行以下操作(在游戏方法中):

create_monkey("some_attr" => "some_value")

答案 1 :(得分:3)

您的Game对象的piles关联集合将具有Active Record提供的buildcreate方法(create方法还会保存关联的对象,假设它通过验证)。

你应该可以这样做:

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

答案 2 :(得分:0)

除了其他人所说的,你应该考虑查看这个week's railscast - 它处理Rails 2.3中的继承资源,特别是在视图中。

第2部分应于下周一(2010-01-18)出现