我有一个模型,它将一些方法和属性委托给不同的模型,比如说
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获取属性值?
答案 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,我将很乐意帮助您进一步帮助您。