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

connection_controller.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

You called your method build_associated_parties after connection is created, so how these methods:

 build_connector
 build_connectee1
 build_connectee2
 build_permission

know what params it will use? So they don't know what values are passed into method then they will get error. In controller, they didn't have error because they used values of params[:connection].

On your form, if you already have fields for connector, connectee1, connectee2, you should put code which initialize object in your new controller. When you save @connection, it's saved those object too. I think these codes aren't need to put into model. Your model only should put other logic code, like search or calculation...

于 2012-11-22T07:38:25.997 に答える
0

ロジックをコントローラーからモデルに戻しました。ただし、build_*コードは、ネストされた属性に渡していた値を上書きしていました。

これらのメソッドにuntil {attribute}を追加するbuild_ことで、適切に値を渡すことができました。

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_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 に答える