在模型中使用self.attribute和attribute之间的区别是什么?

时间:2014-02-26 05:43:26

标签: ruby-on-rails ruby

在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

5 个答案:

答案 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了解更多详细信息。