【问题标题】:Ruby instance variables versus ActiveRecord attributesRuby 实例变量与 ActiveRecord 属性
【发布时间】:2012-06-11 13:13:48
【问题描述】:

我听说 ruby​​ 对象只是我们可以存储实例变量(和类指针)的地方。所以:

class Person
  def initialize(age)
    @age = age
  end
end

现在如果我们运行:

p = Person.new(101)

然后我们得到:

#<Person:0x86cf5b8 @age=101>

太好了,age 属性按预期存储为 实例变量。但是,如果我们将模型转换为从 ActiveRecord 继承,情况会有所不同。现在,在实例化一个新的 Person 之后,我们会看到:

# timestamps removed
#<Person id: 1, age: 101 > 

age 属性似乎不再是实例变量。那么这里到底发生了什么?

我知道我们可以访问 @attributes 实例变量,它包含所有属性和值的散列,所以我想知道 ActiveRecord 是否可能修改控制台输出以以这种方式呈现对象属性。

是否可以在不使用 ActiveRecord 的情况下实例化属性作为属性而不是实例变量的 Ruby 对象?

【问题讨论】:

  • 在您的问题中,非 AR 类中的“属性”与“实例变量”是什么关系?
  • Dave Thomas 在视频中指出,对象只是实例变量的集合。然而 ActiveRecord 对象并不将它们的属性存储为实例变量,所以这让我有点困惑。
  • 为什么? AR 对象不是普通的 Ruby 对象,应该持久化的属性必须与不应该持久化的属性区分开来。 可以使用其他实现机制,但没有使用。
  • AR object aren't plain Ruby objects - 谢谢,这真的解释了。当我开始学习 Ruby 时,我忽略了很多这些东西。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

是的,您可以使用 include ActiveModel::AttributeMethods 扩展一个 ruby​​ 类,以将您的实例变量公开为类似 ActiveModel 的属性。

See the docs 了解更多信息。

【讨论】:

  • 太棒了,现在更有意义了
【解决方案2】:

正如您在代码中看到的那样,将属性“存储”为实例变量是您自己做的,所以如果您想以其他方式保存它们,也取决于您。 ruby 为您提供了方便的类方法来定义 getter 和 setter 方法,例如 attr_accessor。

同样值得注意的是,如果你从 ActiveRecord::Base 继承,你不应该覆盖初始化。

【讨论】:

  • 谢谢,我把 Dave Thomas 的话“对象只是实例变量的集合”理解为它们不能是其他任何东西,但我知道现在还有更多。
【解决方案3】:

我想知道 ActiveRecord 是否可能会修改控制台输出以以这种方式呈现对象属性。

嗯,有点。负责的方法是inspect 和it's implemented by Object,其方式是(我的强调):

...显示对象的类名、对象 id 的编码以及实例变量及其值的列表(通过对每个变量调用 inspect)。

后面还有更多内容:

用户定义的类应该重写此方法以提供更好的 obj 表示。

这正是 ActiveRecord 所做的以及您看到此输出的原因。被覆盖的方法不会列出实例变量,而是显示 AR 属性。

因此,您没有在控制台中看到实例变量并不意味着它不存在!

【讨论】:

    猜你喜欢
    • 2010-10-17
    • 2014-09-21
    • 2011-10-26
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    相关资源
    最近更新 更多