回调是如何调用的?
How are callbacks called?
回调的环境是什么?
例如,在 Rails 教程”(http://rails-4-0.railstutorial.org/book/modeling_users) 中标准 Ruby 的清单 6.20 中有:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
"email"从何而来?我们在一个定义了 email
的函数中吗?或者实际上是 @email
?
此外,我们使用 self.email
而不是 @email
(或者只是 email
,如果它与 @email
相同)是否有重要原因?或者这只是风格上的,还是教学上的?
这里同时发生了几件事:
- 在保存模型实例的上下文中调用该块,因此块中的
self
是要保存的 User
。该块还传递了一个参数,但您不必使用它。
- Ruby 中的局部变量没有显式声明,当您第一次尝试给它们赋值时,它们是隐式声明的。
- 方法调用的隐式接收者是
self
。
- 但是局部变量优先于方法调用,因此增变器方法(例如
self.email=
)需要一个显式接收器来将其与局部变量区分开来。
- 实例变量 (
@email
) 与 ActiveRecord 模型中的 属性 没有任何关系。
- ActiveRecord 对象的访问器(
self.email
或者只是 email
如果没有 email
局部变量)和修改器方法 (self.email=
) 使用属性,而不是实例变量。
所以这个:
before_save { self.email = email.downcase } # (1)
也可以写成:
before_save { |user| user.email = user.email.downcase } # (2)
甚至:
before_save { |user| user.send(:email=, user.send(:email).downcase) } # (3)
主要的功能区别是 (2) 要求 email
和 email=
方法是 public.
回调 运行 在对象(在您的示例中为用户)范围内。 self.email=
是一个对象方法,而@email
是一个实例变量。
ActiveRecord 自动为相应数据库中的所有列创建方法(getter 和 setter)table(我假设您在 users
table 中有 email
列) .
注意,使用 @email =
而不是 self.email =
将创建实例变量并且不会更新数据库中的列。
回调的环境是什么?
例如,在 Rails 教程”(http://rails-4-0.railstutorial.org/book/modeling_users) 中标准 Ruby 的清单 6.20 中有:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
"email"从何而来?我们在一个定义了 email
的函数中吗?或者实际上是 @email
?
此外,我们使用 self.email
而不是 @email
(或者只是 email
,如果它与 @email
相同)是否有重要原因?或者这只是风格上的,还是教学上的?
这里同时发生了几件事:
- 在保存模型实例的上下文中调用该块,因此块中的
self
是要保存的User
。该块还传递了一个参数,但您不必使用它。 - Ruby 中的局部变量没有显式声明,当您第一次尝试给它们赋值时,它们是隐式声明的。
- 方法调用的隐式接收者是
self
。 - 但是局部变量优先于方法调用,因此增变器方法(例如
self.email=
)需要一个显式接收器来将其与局部变量区分开来。 - 实例变量 (
@email
) 与 ActiveRecord 模型中的 属性 没有任何关系。 - ActiveRecord 对象的访问器(
self.email
或者只是email
如果没有email
局部变量)和修改器方法 (self.email=
) 使用属性,而不是实例变量。
所以这个:
before_save { self.email = email.downcase } # (1)
也可以写成:
before_save { |user| user.email = user.email.downcase } # (2)
甚至:
before_save { |user| user.send(:email=, user.send(:email).downcase) } # (3)
主要的功能区别是 (2) 要求 email
和 email=
方法是 public.
回调 运行 在对象(在您的示例中为用户)范围内。 self.email=
是一个对象方法,而@email
是一个实例变量。
ActiveRecord 自动为相应数据库中的所有列创建方法(getter 和 setter)table(我假设您在 users
table 中有 email
列) .
注意,使用 @email =
而不是 self.email =
将创建实例变量并且不会更新数据库中的列。