0

我在包含的模型中遇到 Active Record 回调问题accepts_nested_attributes

build_associated_parties使用after_create回调调用,但这些值没有被保存并且我得到<nil>错误。我也尝试过使用before_create&after_initialize回调但没有成功。

是什么导致回调失败?

连接.rb

class Connection < ActiveRecord::Base 
  attr_accessible :reason, :established, :connector, :connectee1,
                  :connectee2, :connectee1_attributes,
                  :connectee2_attributes, :connector_attributes 

  belongs_to :connector, class_name: "User" 
  belongs_to :connectee1, class_name: "User"
  belongs_to :connectee2, class_name: "User"

  accepts_nested_attributes_for :connector, :connectee1, :connectee2 

  belongs_to :permission 

  after_create :build_associated_parties    

  # builds connectee's, connector, permission objects
  def build_associated_parties   
    build_connector
    build_connectee1
    build_connectee2
    build_permission
  end

连接控制器.rb

class ConnectionsController < ApplicationController
  def new
    @connection = Connection.new
  end

  def create        
    @connection = Connection.new params[:connection]
    if @connection.save     
      flash[:notice] = "Connection created successfully!"
      redirect_to @connection
    else
      render :new
    end
  end
end

但是,如果我改为在控制器内部构建这些属性,如下所示,我不会收到错误消息。这很好,但似乎不利于将业务逻辑代码保留在控制器之外。

class ConnectionsController < ApplicationController
  def new
    @connection = Connection.new
    @connection.build_connectee1
    @connection.build_connectee2
    @connection.build_connector
  end
end

如何使用模型中的代码完成相同的功能?将其保留在模型中是否有优势?

4

3 回答 3

1

您在创建build_associated_parties后调用了您的方法connection,那么这些方法如何:

 build_connector
 build_connectee1
 build_connectee2
 build_permission

知道它将使用什么参数吗?所以他们不知道将什么值传递给方法,然后他们会得到错误。在控制器中,他们没有错误,因为他们使用了params[:connection].

在您的表单上,如果您已经有 的字段connector, connectee1, connectee2,您应该将初始化对象的代码放入新控制器中。当您保存@connection时,它也保存了这些对象。我认为这些代码不需要放入模型中。您的模型只应放置其他逻辑代码,例如搜索或计算...

于 2012-11-22T07:38:25.997 回答
0

将逻辑移出控制器并返回模型。但是,build_*代码覆盖了我传递给嵌套属性的值。

通过将unless {attribute}添加到这些build_方法中,我能够正确传递值。

类连接 < ActiveRecord::Base attr_accessible :reason, :established, :connector, :connectee1, :connectee2, :connectee1_attributes, :connectee2_attributes, :connector_attributes

  belongs_to :connector, class_name: "User"
  belongs_to :connectee1, class_name: "User"
  belongs_to :connectee2, class_name: "User"

  accepts_nested_attributes_for :connector, :connectee1, :connectee2

  belongs_to :permission

  after_initialize :build_associated_parties

  validates :reason, :presence => true
  validates_length_of :reason, :maximum => 160

  #builds connectee's, connector, permission objects
  def build_associated_parties
    build_connector unless connector
    build_connectee1 unless connectee1
    build_connectee2 unless connectee2
  end
于 2012-11-24T06:01:27.497 回答
0

after_create是一个很大的问题。after_initialize在您的模型中使用并在self您的build_associated_parties方法中使用。看看这是否有效。

于 2012-11-22T08:09:15.167 回答