2013-03-23 61 views
1

我得到了经典'Called id for nil...错误,但我很努力地看到为什么我的对象是零。before_add回调,'无对象的被调用ID'错误

当试图抓取任务所属代理的ID时,它在validate_assignee方法中出错。

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我已经改变了在创建行动明确地建立通过用户相关联的任务task.build,并与我知道属于代理人的用户。

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

当我然后输出validate_assignee方法这样puts self.to_yaml我看到的是,工作不具有user_id组内的对象的表示。

因此,在总结 - 我在我的创建行动,但在由before_add协会回调已经失去了与用户的关联调用的方法内的任务模型建立一个新的任务对象通过用户关联。

+0

您的'current_user'是否与'@ user'(您在控制台中测试过的)相同。我认为你的'current_user'没有'agent'。 – codeit 2013-03-23 17:58:20

+0

它是当前已通过身份验证的用户,它属于:代理 – edralph 2013-03-23 18:07:44

+0

什么是您的身份验证用户的用户ID,它会产生错误?一旦你获得用户ID。然后尝试'User.find(id).agent'我认为它是'nil'。 – codeit 2013-03-23 18:31:56

回答

2

看来直到在保存记录,您将无法访问的相关属性物体。那是什么this chap says。相反,我添加了一个after_save回调到我的任务模型来调用我的验证方法,其中一切都按预期工作。

当在验证方法中通过self.to_yaml输出任务时,我看到user_id值与预期的一样。在我能够验证它之前,我必须实际保存记录和habtm协会,这真是一种耻辱。

1

我觉得你没有agent你的current_user。当你没有agentuser

current_user.agent #=> nil 

所以,当nil通话id它抛出错误。

current_user.agent.id #=> Throws error 

如果您还没有agent为每user你可以使用try避免错误:

current_agent_id = self.agent.try(:id) 
+0

可悲的是,这不是每个用户都有一个代理,每个新用户都是通过代理关联创建的,而不是通过User.create创建。我已经仔细检查过,是这种情况。 – edralph 2013-03-23 20:08:37

+0

请参阅最新更新 - 任务在控制器中的创建操作和模型保存之间的某处处失去用户关联。 – edralph 2013-03-23 21:00:42