在before_save中设置参数

时间:2014-10-15 09:19:01

标签: ruby-on-rails ruby activerecord

这不是一个如何回答问题,而是更多的问题。考虑下面的示例,我尝试在保存之前设置默认电子邮件。

class Organization < ActiveRecord::Base
  before_save :set_default_email

  def set_default_email
    email ||= 'info@'+ domain
  end
end

遗憾的是,上述方法不起作用。相反,如果添加如下所示的self,它工作正常,值将传递给db。

  def set_default_email
    self.email ||= 'info@'+domain
  end

然而,鉴于ruby中的默认接收者是self(这就是为什么它理解域等),self.email和email不应该是同一个东西吗?

3 个答案:

答案 0 :(得分:2)

不,Ruby假定构造variable = value是局部变量赋值。这就是为什么在setter方法中,你必须明确地指向接收器。

答案 1 :(得分:2)

只是为了扩展其他答案,如果你分解||=,你得到

email = email || 'info@'+ domain

相当于

email = self.email || 'info@'+ domain

self.email为零,因此会评估为

email = 'info@'+ domain

并设置了一个局部变量,但没有调用email=方法。

这是为什么总是使用self.而不是依赖Ruby的默认范围确定它是一个好习惯的原因之一。它还具有更高的可读性:另一个编码器扫描您的代码可以很容易地看到,当您执行self.email =(或在您的情况下为self.email ||=)时,您需要调用setter方法,而不是定义局部变量。

答案 2 :(得分:1)

如果你不使用self.你正在做的是定义局部变量,而不是调用setter