1

我遇到了经典'Called id for 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

当对象尚未保存时,在这种情况下使用 self 有什么奇怪的吗?有没有更好的方法来做到这一点?我正处于需要另一双眼睛关注的阶段,因为我正在兜圈子。谢谢。

更新: 为了current_user从流程中消除,我更改了 create 操作中的 task.build 以通过用户关联显式构建任务,并使用我知道属于代理的用户。

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

然后当我在这样的validate_assignee方法中输出对象的表示时,puts self.to_yaml我看到 Task 没有user_id集合。

所以总而言之- 我正在通过我的创建操作中的用户关联构建一个新的任务对象,但是在 before_add 关联回调调用的方法内的任务模型中,它已经失去了与用户的关联。

4

2 回答 2

2

似乎在保存记录之前,您无法访问对象的关联属性。这就是这个小伙子说的。因此,我after_save向我的 Task 模型添加了一个回调来调用我的验证方法,在该方法中一切都按预期工作。

通过self.to_yaml验证方法输出任务时,我看到了user_id预期的值。可惜我必须先保存记录和 habtm 关联才能验证它。

于 2013-03-23T21:40:51.290 回答
1

我认为你没有agent你的current_user. 当你没有agentfor 时user

   current_user.agent  #=> nil 

因此,当调用它idnil会引发错误。

   current_user.agent.id #=> Throws error

如果你没有agentfor eachuser你可以try用来避免错误:

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