1

古典的な'Called id for nil...エラーが発生しますが、オブジェクトがnilである理由を確認するのに苦労しています。

validate_assigneeタスクが属する:agentのIDを取得しようとすると、メソッドでエラーが発生します。

class Task < ActiveRecord::Base

belongs_to :user
has_one :agent, through: :users
has_and_belongs_to_many :assignees,
                      class_name: "User",
                      before_add: :validate_assignee
private
  def validate_assignee(assignee)
    #need to check that the :assignee belongs to the same :agent as the :user
    #grab agent_id from self
    current_agent_id = self.agent.id 
    #fails here on create of a Task through the @user.tasks.build association
    ...
  end
end

コンソールから、次の方法でタスクを作成すると、期待される動作が得られます。

> task = @user.tasks.build ...
> task.agent.id
=> 1

TasksControllerでの作成アクション:

def create
  @task = current_user.tasks.build(params[:task])
  ...
end

オブジェクトがまだ保存されていないときに、このコンテキストで自分自身を使用することについて何か奇妙なことがありますか?これを行うためのより良い方法はありますか?ぐるぐる回っているので、もう一組目が必要な段階です。ありがとう。

更新:プロセス から削除するためcurrent_userに、createアクションのtask.buildを変更して、ユーザーの関連付けを介して、エージェントに属していることがわかっているユーザーを使用してタスクを明示的にビルドしました。

@task = User.find(1).tasks.build(params[:task])

validate_assignee次に、このようにメソッド内のオブジェクトの表現を出力するputs self.to_yamlと、タスクにセットがないことがわかりますuser_id

要約すると、createアクションのUserアソシエーションを介して新しいタスクオブジェクトを構築していますが、before_addアソシエーションコールバックによって呼び出されたメソッド内のタスクモデルでは、Userとのアソシエーションが失われています。

4

2 に答える 2

2

レコードが保存されるまで、オブジェクトの関連するプロパティにアクセスできないようです。それはこのチャップが言うことです。その代わりにafter_save、タスクモデルにコールバックを追加して、すべてが期待どおりに機能する検証メソッドを呼び出しました。

self.to_yaml検証メソッドでタスクを出力すると、user_id期待どおりの値が表示されます。検証する前に、レコードとhabtmアソシエーションを実際に保存する必要があるのは残念です。

于 2013-03-23T21:40:51.290 に答える
1

私はあなたがあなたのために持っていないと思いagentますcurrent_useragentあなたが持っていないときuser

   current_user.agent  #=> nil 

したがって、それを呼び出すとidエラーnilがスローされます。

   current_user.agent.id #=> Throws error

エラーを回避するために使用できるagentすべてのものがない場合:usertry

   current_agent_id = self.agent.try(:id)
于 2013-03-23T18:47:36.843 に答える