Parent.build中的父项为nil

时间:2015-05-20 21:26:31

标签: ruby ruby-on-rails-4

模型如:

class Forrest < ActiveRecord::Base
  has_many :trees, inverse_of: :forrest
  has_many :oak_trees, inverse_of: :forrest
  has_many :palm_trees, inverse_of: :forrest
end

class Tree < ActiveRecord::Base
  belongs_to :forrest, inverse_of: :trees
end

class OakTree < Tree
  def height=(value)
    # Stuff
  end
end

然后这个:

forrest = Forrest.create
forrest.oak_trees.build(height: :tall)

我需要height=方法forrest,但它没有。我认为必须有一些方法来纠正这个问题。

我尝试将belongs_toTree移到子类并添加inverse_of: oak_trees

但我无法弄清楚如何使其发挥作用。

2 个答案:

答案 0 :(得分:1)

以这种方式无法访问未保存的模型。它们之间的关系尚未形式化,相关模型尚未存在。

ActiveRecord通常非常适合填补空白,但传递创建范围的信息的方式是通过ID,而不是对象,并且由于您的Forest记录未被保存,因此它不会还存在。

ActiveRecord处理此问题的方法是将未保存的记录保留在oak_trees缓存结构中。保存后,它们会正常烘烤。

这将有效:

forest = Forest.create
tree = forest.oak_trees.build(height: tall)

如果您在保存之前需要访问权限,则可能需要进行大量修改,或者您可以通过以下方式创建它们:

forest = Forest.new
tree = OakTree.new(forest: forest, height: tall)

答案 1 :(得分:0)

这是猜测,但也许rails会在设置父级之前设置您传递的属性。

那么,这有用吗?

oak = forrest.oak_trees.build
oak.height = :tall

同时尝试带有块的版本

forrest.oak_trees.build { |o| o.height = :tall }