Ruby gem расширяет класс методами, определенными в блоке - PullRequest
0 голосов
/ 28 сентября 2011

Я создаю гем и хотел иметь возможность изменять объект ActiveRecord, динамически создавая методы получения и установки атрибутов для сериализованного атрибута.Например:

class User
  has_serialized :setting do |config|
    config.define :notify_by_email, default: true
    config.define :notify_by_phone, default: true
  end
end

user = User.new
user.notify_by_email? # true
user.notify.by_phone? # true
user.notify_by_email = false
user.notify_by_phone = false
user.notify_by_email? # false
user.notify.by_phone? # false

Я понимаю, что мне нужно будет расширить ActiveRecord с помощью модуля, содержащего метод has_serialized, и что мне нужно будет использовать define_method для добавления пользовательских методов получения и установки, однако яне могу понять, как объединить два, используя синтаксис блока, который я хочу для определения.Есть идеи?

1 Ответ

1 голос
/ 28 сентября 2011

Вы можете создать класс, расширяющий хеш, используемый для захвата ваших параметров, а затем выполнить блок с помощью класса. Закончив, вы можете перебрать свой метод определения захвата. Вот пример:

class Initializer < Hash
  def define(settings, options = {})
    self[setting] = options
  end
end

module ClassMethods
  def has_serialized(name, &block)
    initializer = Initializer.new
    block.call(initializer)
    initializer.each do |method, options|
      define_method "#{method}?" do
        ...
      end
      define_method "#{method}=" do |value|
        ...
      end
    end
  end
end
...