简体   繁体   English

Ruby gem扩展类具有在块中定义的方法

[英]Ruby gem extend class with methods defined in a block

I am creating a gem and wanted to be able to modify an ActiveRecord object by creating attribute getters and setters dynamically to a serialized attribute. 我正在创建一个gem,并希望能够通过动态创建属性getter和setter到序列化的属性来修改ActiveRecord对象。 For example: 例如:

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

I realize that I will need to extend ActiveRecord with a module containing the method has_serialized and that I will need to use define_method to add the custom getters and setters, however I can't figure out how to combine the two using the block syntax I want for definition. 我意识到我将需要使用包含has_serialized方法的模块来扩展ActiveRecord,并且需要使用define_method来添加自定义getter和setter,但是我无法弄清楚如何使用所需的块语法将两者结合起来用于定义。 Any ideas? 有任何想法吗?

You can create a class that extends hash used to capture your parameters then execute the block using the class. 您可以创建一个扩展用于捕获参数的哈希的类,然后使用该类执行该块。 Once finished, you can iterate over your capture performing define method. 完成后,您可以遍历捕获执行的define方法。 Here is an example: 这是一个例子:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM