1

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

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 或通过检查来访问委托属性。有没有机会通过read_attribute获取属性值?

4

2 回答 2

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,我将很乐意尝试并进一步帮助您。

于 2013-02-19T15:41:19.533 回答
0

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

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

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

于 2013-02-19T07:29:27.733 回答