ActiveModel динамические методы в объектах экземпляра - PullRequest
0 голосов
/ 10 января 2012

Я использую ActiveModel в одном из своих проектов, и я хотел спросить, как лучше определить динамические методы в следующей ситуации

Базовый класс ActiveModel имеет только 1 атрибут доступа, называемый атрибутами.

  def initialize(attributes = {})
      set_default_attributes!
      @attributes.merge!(attributes.symbolize_keys)
      @new_record = true    
   end

   def read_attribute_for_validation(key)
      @attributes[key]
   end


   def self.create(attributes={})
     obj = self.new(attributes)
     obj.save
     return obj
   end

   def save
     if self.valid?
       puts "saved!"
       return true
     end   
     return false
  end    


  def update_attributes(attributes={})
     self.attributes.merge!(attributes.symbolize_keys)
     self.save
  end     



  def as_json(options={})
      hash = Hash.new
      hash.merge!(self.attributes)
      hash.as_json({:root=>false}.merge!(options || {}))

  end  

методы должны быть похожи на методы доступа, но должны использовать внутреннюю переменную @attributes

Пример, если @attributes имеет хеш-код, подобный {:param1=>1,:param2=>2}

экземпляр объекта должен иметь следующие методы

param1
param1=
param2
param2=

Я пытался использовать метод отсутствующий, но если метод завершился с "=", мне нужно проанализировать его и проверить атрибуты для такого ключа, поэтому мне не нравится, как выглядит код.

1 Ответ

1 голос
/ 20 января 2012

вы можете добавить методы с помощью singleton_class.module_eval

def initialize(attributes = {})
   set_default_attributes!
   @attributes.each do |key,value|
     singleton_class.module_eval do
       define_method(key) { self.attributes[key] } unless method_defined? key
       define_method("#{key}=") { |new_value|  self.attributes[key] = new_value } unless method_defined? "#{key}="
     end
   end
   @attributes.merge!(attributes.symbolize_keys)
   @new_record = true

 end
...