嵌套属性和通过控制器添加属性?

时间:2009-12-29 18:11:17

标签: ruby-on-rails nested-attributes

由于这个问题难以描述,这是我能提出的最佳标题,所以这里有一些代码。

鉴于三种模式Parent,Child&&孙子。

Parent <  ActiveRecord::Base
  has_many :children
  has_many :grandchildren
  accepts_nested_attributes_for :child
end

Child <  ActiveRecord::Base
  belongs_to :parent
  has_many :kids, :as => :grandchildren #this is just an example
  accepts_nested_attributes_for :grandchild
end

Grandchild <  ActiveRecord::Base
  belongs_to :parent
  belongs_to :child
end

我想将current_user.id添加到在Parent#new期间创建的子记录和Grandchild记录中。我现在使用隐藏字段,因为我找不到添加它们的好方法。

也许有人可以通过创建回调来在创建时添加current_user.id来提供帮助?无论如何,我从未有过很多运气,但你很聪明。

思想?

2 个答案:

答案 0 :(得分:5)

嗯,首先,我建议从父母到孙子(通过孩子)建立has_many :through关系,反之亦然。有关详细信息,请参阅the ActiveRecord Association Class Methods API中的“关联加入模型”部分。

关于你的主要问题,就像你说的那样,回调可能就是你想要的。我认为这样的事情应该这样做(尽管这是未经测试的代码):

class Parent
  # ...somewhere at the top...
  before_create :set_current_user_on_descendants

  # ...somewhere in the main class body...
  # (I assume parent['current_user'] is passed in as a typical 
  # parameter, and thus self.current_user is already set.)
  def set_current_user_on_descendants
    children.each { |c| c.current_user = self.current_user }
    grandchildren.each { |gc| gc.current_user = self.current_user }
  end
end

有一些风格点可以用不同的方式完成。例如,你可以定义一个“后代”方法返回子孙子孙并迭代它,或者你可以在子孙子类上实现回调(在这种情况下你可能想把它拉出来一个模块最大化) DRYness,虽然只有两个类中的单行方法可能是矫枉过正的)。根据您要更新current_user的确切时间,您可能希望使用before_save或其他一些回调而不是before_create - 您可以在the ActiveRecord callbacks API中找到可用回调的完整列表。< / p>

答案 1 :(得分:0)

我想它也可以覆盖默认的save!方法

class Parent < ActiveRecord::Base
   def save! 
      children.each { |c| c.current_user = @current_user }
      grandchildren.each { |gc| gc.current_user = @current_user }

      super
   end
end

未经测试。不确定这会起作用......