5

属性が処理される方法でRails AactiveRecordモデルと同様に機能するRubyクラスを作成しようとしています:

class Person
  attr_accessor :name, :age

  # init with Person.new(:name => 'John', :age => 30)
  def initialize(attributes={})
    attributes.each { |key, val| send("#{key}=", val) if respond_to?("#{key}=") }
    @attributes = attributes
  end

  # read attributes
  def attributes
    @attributes
  end

  # update attributes
  def attributes=(attributes)
    attributes.each do |key, val| 
      if respond_to?("#{key}=")
        send("#{key}=", val) 
        @attributes[key] = name
      end
    end
  end
end

つまり、クラスを初期化すると、「属性」ハッシュが関連する属性で更新されます。

>>> p = Person.new(:name => 'John', :age => 30)
>>> p.attributes
 => {:age=>30, :name=>"John"}
>>> p.attributes = { :name => 'charles' }
>>> p.attributes
 => {:age=>30, :name=>"charles"}

ここまでは順調ですね。私がしたいのは、個々のプロパティを設定したときに属性ハッシュを更新することです。

>>> p.attributes
 => {:age=>30, :name=>"John"}
>>> p.name
 => "John"
>>> p.name = 'charles' # <--- update an individual property
 => "charles"
>>> p.attributes
 => {:age=>30, :name=>"John"} # <--- should be {:age=>30, :name=>"charles"}

を使用する代わりに、すべての属性に対してセッターとゲッターを作成することでそれを行うことができますがattr_accessor、それは多くのフィールドを持つモデルには適していません。これを達成する簡単な方法はありますか?

4

1 に答える 1

7

問題は、属性を別々の ivar として保持し、@attributesハッシュ内に保持することです。1 つの方法のみを選択して使用する必要があります。

ハッシュを使用する場合は、アクセサーを作成する独自の方法を作成する必要があります。これにより、アクセサーは、ハッシュを設定および取得する単一のメソッドに「再ルーティング」されます。

class Class  
 def my_attr_accessor(*accessors)
   accessors.each do |m|

     define_method(m) do  
       @attributes[m]
     end        

     define_method("#{m}=") do |val| 
       @attributes[m]=val
     end
   end
 end
end

class Foo
  my_attr_accessor :foo, :bar

  def initialize
    @attributes = {}
  end
end

foo = Foo.new

foo.foo = 123
foo.bar = 'qwe'
p foo
#=> #<Foo:0x1f855c @attributes={:foo=>123, :bar=>"qwe"}>

ivar を使用する場合は、独自のattr_accessorメソッドを作成する必要があります。さらに、どの ivar を「属性」にする必要があるかを記憶し、そのリストをattributesメソッドで使用する必要があります。attributesメソッドはその場でそれらからハッシュを作成し、それを返します。

ここでは、アクセサーの実装に関する素晴らしい記事を見つけることができます。

于 2010-07-15T14:47:18.667 に答える