模型中的实例变量

时间:2015-12-27 20:12:15

标签: ruby-on-rails

假设我的模型Foo带有bar列。

我习惯于定义模型的实例方法,如下所示:

class Foo < ActiveRecord::Base
def do_smth
self.bar.capitalize!
end
end

但这是在self上调用getter方法,它应该只是@bar.capitalize!的更长的方式。

就像在Rails中一些东西是隐藏的(例如初始化Base类)我不确定。它会起作用吗?

1 个答案:

答案 0 :(得分:1)

这里有很多混乱,所以让我们从顶部开始:

Ruby是关于消息传递的 - 当你在对象上调用方法时,隐式接收者就是对象本身:

def do_smth
  self.bar.capitalize!
end

相当于:

def do_smth
  bar.capitalize!
en

所以让我们举几个例子:

class Thing

  def initialize
    @foo = 1
  end

  def test
    foo # NameError: undefined local variable or method `foo'
  end

  def test2
    @bar # nil
  end
end

那么,为什么这会失败?因为在Ruby中,实例变量的范围限定为实例,并且只能使用sigil @访问。 Ruby不会自动将@foo映射到Thing#foo。实例变量Ruby甚至允许您访问未初始化的ivars(@bar)。

除非我们创建一个访问者:

class Thing

  def foo
    @foo
  end

  def test
    foo # nil
  end
end

可以使用速记宏attr_readerattr_accessor来完成。

class Thing
  attr_reader :foo # read only
  attr_accessor :foo # rw

  def test
    foo # nil
  end
end

如果您从Rails开始而不了解Ruby如何执行OOP,这可能会非常令人困惑,因为Active Record会读取您的数据库表并创建getter和setter&#34;神奇地&#34;适用于所有模型属性。

在这种情况下你需要记住的一件事是使用@some_column不会调用任何getter / setter方法。这可能会导致Rails脏状态跟踪问题,以及在设置器中进行类型转换的日期列等情况。