50

在 Rails 模型中测试 getter/setter 对时,我发现了一个我一直认为奇怪且不一致的行为的好例子。

在这个例子中,我正在处理class Folder < ActiveRecord::Base.

Folder belongs_to :parent, :class_name => 'Folder'

在 getter 方法上,如果我使用:

def parent_name
  parent.name
end

...或者...

def parent_name
  self.parent.name
end

...结果完全一样,我得到了父文件夹的名称。但是,如果我使用 getter 方法...

def parent_name=(name)
  parent = self.class.find_by_name(name)
end

... parent 变为 nil,但如果我使用...

def parent_name=(name)
  self.parent = self.class.find_by_name(name)
end

...然后它的工作原理。

所以,我的问题是,为什么有时需要声明 self.method 以及为什么只能使用局部变量?

似乎selfActiveRecord 中对/​​使用的需求不一致,我想更好地理解这一点,所以我不觉得我总是在猜测我是否需要声明自己。什么时候应该/不应该在 ActiveRecord 模型中使用 self ?

4

1 回答 1

88

这是因为属性/关联实际上是方法(getter/setter)而不是局部变量。当您声明“parent = value”时,Ruby 假定您要将值分配给局部变量 parent。

在堆栈的某处,有一个 setter 方法“def parent=”,要调用它,您必须使用“self.parent =”告诉 ruby​​,您实际上想要调用 setter 而不仅仅是设置局部变量。

当谈到 getter 时,Ruby 会首先查看是否存在局部变量,如果找不到,它会尝试查找具有相同名称的方法,这就是为什么您的 getter 方法可以在没有“self”的情况下工作的原因。

换句话说,这不是 Rails 的错,而是 Ruby 天生的工作方式。

希望有帮助。

于 2011-03-03T16:59:29.220 回答