3

由于这个问题很难描述,这是我能想到的最好的标题,所以这里有一些代码。

给定三个模型 Parent、Child && Grandchild。

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 期间创建的子记录和孙子记录中。我现在使用隐藏字段,因为我找不到添加它们的好方法。

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

想法?

4

2 回答 2

5

好吧,一方面,我建议has_many :through从父母到孙子(通过孩子)建立关系,反之亦然。有关详细信息,请参阅ActiveRecord 关联类方法 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或其他一些回调来代替- 您可以在ActiveRecord 回调 APIbefore_create中找到可用回调的完整列表。

于 2009-12-29T19:06:49.793 回答
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

也未经测试。不太确定这会奏效......

于 2009-12-29T21:52:17.853 回答