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

問題は、メソッドを呼び出すことで「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 で属性値を取得する機会はありますか?

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 を使用していませんが、同様のシナリオでハッシュ メソッドをオーバーライドする必要がありました。

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 に答える