Rails委托属性不在@attributes中,read_attribute返回nil

时间:2013-01-03 13:27:25

标签: ruby-on-rails

我有一个模型,它将一些方法和属性委托给不同的模型,比如说

class ModelOne < ActiveRecord::Base
  # this model has some_property column in database
end

class ModelTwo < ActiveRecord::Base
  belongs_to :model_one

  delegate :some_property, :to => :model_one
end

问题是我可以通过调用方法而不是通过read_attribute访问'some_property'。

> obj1 = ModelTwo.last
> obj1.some_property
=> "some value"
> obj1.read_attribute :some_property
=> nil
> obj1.inspect
=> "#ModelTwo ... , ... , some_property: nil "

可以设置此属性:

> obj1.some_property = "some value"
> obj1.inspect
=> "#ModelTwo ... , ... , some_property: "some value" "

所以我可以通过调用它来访问委托属性,但不能通过read_attribute或通过inspect来访问。是否有机会通过read_attribute获取属性值?

2 个答案:

答案 0 :(得分:0)

也许您应该尝试覆盖read_attribute方法。我没有使用read_attribute,但在类似的情况下我不得不重写哈希方法:

def [](key)
  value = super
  return value if value
  if super(key+"_id")
    begin
      send(key)
    rescue NoMethodError
    end
  end
end

它不漂亮,在没有更准确的验证的情况下调用 send(key)可能存在安全问题。

答案 1 :(得分:0)

如果你研究一下read_attribute的实现:

         # File activerecord/lib/active_record/attribute_methods/read.rb, line 128
          def read_attribute(attr_name)
             self.class.type_cast_attribute(attr_name, @attributes, @attributes_cache)
          end

不是基于属性访问器(在你的情况下是some_property),而是直接访问@attributes实例变量,这是有道理的,因为read_attribute是一个允许你绕过访问器的低级api。因此,你不能做你正在尝试的事情。

这可能不是您正在寻找的答案,但我在您的设计中重新考虑的是您需要通过read_attribute访问您的属性的原因。如果您告诉我们您在何处以及如何使用read_attribute,我将很乐意帮助您进一步帮助您。