为什么 ruby​​/rails/activerecord 中并不总是需要 self ?

发布于 2024-10-19 21:35:27 字数 852 浏览 7 评论 0原文

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

在此示例中,我正在处理 class Folder < ActiveRecord::Base

文件夹属于:父级,: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 以及为什么可以只使用局部变量?

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

In testing a getter/setter pair in a rails model, I've found a good example of behavior I've always thought was odd and inconsistent.

In this example I'm dealing with class Folder < ActiveRecord::Base.

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

On the getter method, if I use:

def parent_name
  parent.name
end

...or...

def parent_name
  self.parent.name
end

...the result is exactly the same, I get the name of the parent folder. However, in the getter method if I use...

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

... parent becomes nil, but if I use...

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

...then then it works.

So, my question is, why do you need to declare self.method sometimes and why can you just use a local variable?

It seems the need for / use of self in ActiveRecord is inconsistent, and I'd like to understand this better so I don't feel like I'm always guessing whether I need to declare self or not. When should you / should you not use self in ActiveRecord models?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江湖正好 2024-10-26 21:35:27

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

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

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

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

This is because attributes/associations are actually methods(getters/setters) and not local variables. When you state "parent = value" Ruby assumes you want to assign the value to the local variable parent.

Somewhere up the stack there's a setter method "def parent=" and to call that you must use "self.parent = " to tell ruby that you actually want to call a setter and not just set a local variable.

When it comes to getters Ruby looks to see if there's a local variable first and if can't find it then it tries to find a method with the same name which is why your getter method works without "self".

In other words it's not the fault of Rails, but it's how Ruby works inherently.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文