(更新:图片中的拼写错误):
after_initialize :set_default_role, :if => :new_record?
所以考虑到上面的代码,我很好奇有:if => :new_record?
语法的名称吗?
为什么将if
语句写成哈希?
如果写成:
,是否有区别?after_initialize :set_default_role if self.new_record?
答案 0 :(得分:1)
首先,代码中的after_initialize
语法不正确。
而不是:
after_initialize: set_default_role
,
你应该致电
<强> after_initialize :set_default_role
强>
那就是说,after_initialize
这是来自类体的正常方法调用(是的,它可能在Ruby中)。当加载类时,它被称为一次。调用此方法时,会设置一个回调(第一个参数),在这种情况下,当您的Active Record对象被实例化时,将被触发。
在这种情况下,:if
是传递给after_initialize
方法的关键选项。它就像你调用这样的方法一样:
after_initialize(:set_default_role, { if: :new_record? })
第二个参数 :带有一些选项的哈希对象。
请注意::if => :new_record?
( hashrocket notation )与if: :new_record?
(新语法,类JSON )相同。
所以,if
这里只是选项Hash Object作为方法调用的第二个参数传递的键名(而不是条件if
关键字)。 / p>
顺便说一下,您可以详细了解条件回调 here。
<小时/> 为什么
after_initialize :set_default_role if self.new_record?
无法工作?
那是因为这个方法是在类体中调用的,具有类上下文(self = User
,而不是self = @user
) - 一旦加载 - ,new_record?
是一个实例方法。解释器会抛出undefined method 'new_record?'
错误。
当您将if:
键正确设置为:new_record?
时,它就像指针一样。您正在说:好的,我现在定义,在我的类上下文中,当时间到来时(此Active Record对象被实例化),您将查找名为{{1}的方法}在我的班级实例中,但前提是实例方法set_default_role
返回new_record?
。