在Ruby on Rails中,在模型中使用self.attribute和attribute有什么区别?
在此示例中,假设my_attr是存储在数据库中的用户的属性。
class User < ActiveRecord::Base
def do_something!
self.my_attr = 123
end
def do_another_thing!
my_attr = 456
end
end
答案 0 :(得分:19)
区别在于一个有效,另一个没有 - 或者至少不是你想要的。
你的第二个版本没有做任何事情。它不等同于调用self.my_attr = 123
,而只是创建一个名为my_attr
的局部变量并将其设置为123
,然后在方法返回时将其抛出。它不会以任何方式影响模型的my_attr
值。
class User < ActiveRecord::Base
def do_another_thing!
my_attr = 456
puts self.my_attr # nil (or whatever value it was before)
end
end
相反,如果您想访问在对象上定义的方法,您可以(和should)省略self
:
class User
def name=(value)
@name = value
end
def name
@name
end
def age=(value)
@age = value
end
def age
@age
end
def do_something
self.name = "bob" # self is required
puts name # bob (self.name)
age = 47 # @age is unaffected
age # 47 (local variable), but self.age is nil
end
end
请注意,这不是Rails问题,而是一个Ruby问题。这里没有特定于Rails的代码,这种行为是Ruby语法工作方式的一部分。
答案 1 :(得分:4)
一般规则是,无论何时通过为某些属性赋值来修改self,都要明确使用“self”
self.first_name = 'Prasad' #if self isnt used, it will create a local variable.
如果您要引用该属性(但不修改),请不要使用“self”
def name
name.camelize
end
---- ----- UPDATE
每当我们访问任何属性时,ruby将检查是否定义了该属性的getter(reader)和setter(writer)方法。
因此,在上述情况下(当您为属性赋值时),您不会直接访问该属性,而是将值传递给setter,该setter将在内部将值赋给该属性。
2.1.0p0 :008 > User.first.first_name
=> "Prasad"
2.1.0p0 :009 > (User.first.methods - Object.methods).include? :first_name
=> true
2.1.0p0 :010 > (User.first.methods - Object.methods).include? :first_name=
=> true
您可以通过向任何模型添加方法来尝试
def some_name
first_name = 'Some name'
puts self.first_name
self.first_name = 'Random Username'
puts self.first_name
end
并重新加载控制台并执行
2.1.0p0 :017 > User.first.some_name
Prasad
Random Username
=> nil
答案 2 :(得分:0)
do_something!是一种实例方法。所以这里的self是User实例,my_attr =是你的User实例的方法。该函数是为用户实例变量@may_attr。
分配值在“do_another_thing!”中,my_attr可能是您刚刚声明的变量。
答案 3 :(得分:0)
在这种情况下没有区别。但假设您在方法定义中有一个局部变量:
def do_something!
self.my_attr = 123
end
def do_another_thing!(my_attr)
puts "my_attr is #{my_attr}"
puts "self.my_attr is #{self.my_attr}"
end
do_something!
do_another_thing!(456)
然后输出
my_attr is 456
self.my_attr is 123
self
代表一个对象。当您在self
上调用方法时,您专门在该对象上调用方法。
答案 4 :(得分:0)
Ruby中的关键字self允许您访问当前对象 - 接收当前消息的对象。
所以self.attribute
引用current object's attribute
,其中只有attribute
的{{1}}。
阅读本指南self了解更多详细信息。