在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

... 家长变为零,但如果我使用...

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

...然后就行了.

所以,我的问题是,为什么你需要声明自己.方法,为什么只能使用局部变量?

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

推荐答案

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

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

当谈到getter时,Ruby首先查看是否存在局部变量,如果找不到,则try 找到一个同名的方法,这就是为什么getter方法不使用"self"的原因.

换句话说,这不是Rails的错,而是Ruby固有的工作方式.

希望有帮助.

Ruby相关问答推荐

Ruby错误-应为数组或字符串,已获取哈希

我可以在Ruby中以散列的形式访问方法的关键字参数吗?

带有(*)签名的Ruby方法

ruby 中嵌套哈希中相同键的平均值

Rails 7 - 访问连接模型生成新查询

RSpec 中有没有一种方法可以同时断言调用次数和参数列表?

Rb:仅通过在 Ruby 中的类上添加 each 方法,可枚举模块是如何工作的?

厨师从源代码安装和更新程序

在Ruby中将嵌套哈希键从CamelCase转换为snake_case

Kernel#gets try 读取文件而不是标准输入

使用 Homebrew 安装 Ruby

如何找到安装 Ruby Gem 的路径(即 Gem.lib_path c.f. Gem.bin_path)

如何仅从 Gemfile 中查看依赖关系树?

在Ruby中实现平等的正确方法是什么

使用 `?`(问号)在 Ruby 中获取 ASCII 字符代码失败

如何在 Ruby 中编写复杂的多行 if 条件?

如何传递函数而不是块

向实例对象添加方法

如何在文件夹及其所有子文件夹中搜索特定类型的文件

查找两个数组的共同点