【问题标题】:nested attributes and adding attributes through the controller?嵌套属性和通过控制器添加属性?
【发布时间】:2009-12-29 18:11:16
【问题描述】:

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

给定三个模型 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 来提供帮助?无论如何,我从来没有把它变成模型的运气,但你很聪明。

想法?

【问题讨论】:

  • 谁能更新 Rails 3 的响应?

标签: ruby-on-rails nested-attributes


【解决方案1】:

嗯,一方面,我建议从父母到孙子(通过孩子)建立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 中找到可用回调的完整列表。

【讨论】:

  • 我一定会检查的。感谢您的透彻,虽然我熟悉回调并且我的例子不在我的脑海中,但这些信息将帮助其他人。当我测试时,我会标记为完成,因为它看起来应该可以工作。
  • 很好地传递了@current_user 并没有做任何事情,但是我只是从self.user_id 为每个后代窃取了user_id 列。如果您想将其添加到其中,我想将您的答案标记为完整。
【解决方案2】:

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

也未经测试。不太确定这是否可行...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2018-04-12
    • 1970-01-01
    相关资源
    最近更新 更多