代码之家  ›  专栏  ›  技术社区  ›  pjammer

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

  •  3
  • pjammer  · 技术社区  · 15 年前

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

    父母、子女和孙子有三种模式。

    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
    

    我想将当前的user.i d添加到父级新建期间创建的子级记录和孙子级记录中。我现在使用隐藏字段,因为我找不到添加它们的好方法。

    也许有人可以通过创建回调来帮助您在创建时添加当前的\u user.id?不管怎么说,我从来没有把它做成模特儿,但你很聪明。

    思想?

    2 回复  |  直到 15 年前
        1
  •  5
  •   John Hyland    15 年前

    嗯,首先,我建议 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
    

    有一些风格上的观点可以用不同的方式来做。例如,您可以定义一个“后代”方法,该方法返回子代+孙子代并对其进行迭代,或者您可以对子代和孙子代类实现回调(在这种情况下,您可能希望将其拉入模块以获得最大的干燥度,但对于只有两个类中的一行方法,这种方法可能会被过度杀死)。根据您想更新当前用户的确切时间,您可能想使用 before_save 或其他回调而不是 before_create -您可以在中找到可用回调的完整列表 the ActiveRecord callbacks API .

        2
  •  0
  •   Lukas    15 年前

    我想它也可以覆盖默认值 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
    

    也未经测试。不太确定这会起作用…