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



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

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

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

> 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获得属性值?

也许你应该尝试重写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)可能存在安全问题。

如果您查看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,我很乐意尝试帮助你。

最新更新