我遇到了经典的'Called id for nil...
错误,但我很难理解为什么我的对象为零。
尝试获取任务所属的代理的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
当对象尚未保存时,在此上下文中使用self有什么奇怪之处吗?有没有更好的方法呢?我正处于我需要另一双眼睛的阶段,因为我正绕着圆圈走。感谢。
更新
为了从流程中消除current_user
,我已经在create action中更改了task.build,以通过User关联显式构建任务,并且我知道的User属于代理。
@task = User.find(1).tasks.build(params[:task])
当我在validate_assignee
方法中输出对象的表示时,如puts self.to_yaml
,我发现任务没有设置user_id
。
总结 - 我正在通过我的创建操作中的用户关联构建一个新的Task对象,但是在由before_add关联回调调用的方法内的Task模型中,它已经失去与用户。
答案 0 :(得分:2)
似乎,在保存记录之前,您无法访问该对象的关联属性。这就是this chap says。相反,我已经在我的Task模型中添加了一个after_save
回调来调用我的验证方法,其中一切都按预期工作。
在验证方法中通过self.to_yaml
输出任务时,我会按预期看到user_id
值。在我验证它之前,我必须实际保存记录和habtm关联,这简直是一种耻辱。
答案 1 :(得分:1)
我认为您的agent
没有current_user
。如果agent
没有user
:
current_user.agent #=> nil
因此,在id
上调用nil
时会抛出错误。
current_user.agent.id #=> Throws error
如果您agent
没有user
,则可以使用try
来避免错误:
current_agent_id = self.agent.try(:id)