为什么要使用"self"来访问ActiveRecord/Rails模型属性?

14

在我的应用程序中,不需要使用self.来引用用户的名称,name就可以正常工作。

为什么以下代码需要self才能按预期工作?

class User< ActiveRecord::Base
    before_save :validate_name

def validate_name
    if self.name.nil? || self.name.empty?
        self.name= "Mr. No Name"
    end
end

顺便说一下,我知道validates_presence_of可以用来防止保存,但如果没有给出名称,我想使用默认值保存。

Rails 3.0.7。

1个回答

24

通常使用self是为了让Ruby将其识别为方法调用,而不是将其误解为变量。如果没有关于day=这个方法的先前知识,那么day = "x"会被Ruby视为变量赋值语句。而self.day = "x"则始终是一个方法调用。

这个问题的原因是在User类文件被解析之后,namename=方法是动态添加的。当使用模型时,Rails首先会为相关的数据库字段创建方法,但这发生在解析user.rb文件之后。


抱歉,self.day 应该是 self.name!我已经更新了问题。 - B Seven
7
Nit: Ruby永远不会将x = y解析为一个方法调用。它总是直接将其解析为变量(或常量,根据情况)赋值。表达式x的形式取决于当前作用域中是否存在变量x - user166390
那么,使用self.name而不是name是最佳实践吗? - B Seven
2
@BSeven 表达式 name 的意思是“本地变量名称”,仅当 name 已经绑定(分配)时。在其他所有时间,它的意思是 self.name。表达式 name = y 总是将 y 分配给 变量 name。我更喜欢避免使用重载名称。对于设置器,始终需要 obj.attr = v。;-) - user166390
1
注意2:在Ruby中,“class”不再比后来添加的动态方法“特殊”。它只是一个表达式,不会“添加上下文”以影响Ruby如何处理“x”或“x =”(即使“定义在“class”表达式内部”,这也永远不会成为一个方法调用)。无论如何,在某些地方我发现回答有点误导性,但仍然给予+1的评价。 - user166390
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接