【问题标题】:Rails - How to define setter/getter dynamically for list of methods inside a classRails - 如何为类中的方法列表动态​​定义 setter/getter
【发布时间】:2014-11-06 19:50:12
【问题描述】:

我有一个通知模块,其中包含 1)汽车 2)自行车 3)飞机等类。我在 UserFeature 模型中有一个序列化列。我有一个模块“通知”,其中包含 11 个类的列表。

Notifications
 1)car
 2)bike
 3)Aeroplane

UserFeature 模型中通知栏的哈希结构必须是

 {:car => {:mirror => :true, :door => :true}
  :bike => {:x=> :true, :x => :true}
  :Aeroplane => {:p => :true, :q => :true}
 }

我可以访问 user_object.Notifications 但是为了访问 user_object.car 和 user_object.mirror 我需要编写 getter/setter 方法 { 动态定义 getter/setter 因为我不想为每个方法编写 getter/setter 而且我不确定数字我拥有的方法 -> 将来可能会扩展 }

     Notifications.constants.each do |notification_class|
    class_methods = "Notifications::#{notification_class}".constantize.methods(false)
    class_methods.each do |method|
     method_name = method[0..-4].split('(')[0]
      setter_getter_name = "#{notification_class.to_s.underscore}_#{method_name}"

     define_method("#{setter_getter_name}=") do |value|
        self.notifications = GlobalUtils.form_hash(self.notifications, "#{notification_class}".to_sym, "#{method_name}".to_sym)
        self[:notifications]["#{notification_class}".to_sym][ "#{method_name}".to_sym]  = value
     end

    define_method("#{setter_getter_name}") do
       self.notifications.fetch("#{notification_class_name}".to_sym, {}).fetch("#{method_name}".to_sym)
     end

end
end

但是当我尝试访问 user_object.mirror 时,

     undefined method for #<UserFeature000043645345>

我做错了什么? 我只需要使用 getter/setter 方法来做到这一点

【问题讨论】:

    标签: ruby-on-rails dynamic getter-setter


    【解决方案1】:

    OpenStruct 是一种类似于 Hash 的数据结构,它允许定义任意属性及其伴随值。这是通过使用 Ruby 的元编程在类本身上定义方法来实现的。

    示例:

    require 'ostruct'
    hash = { "country" => "Australia", :population => 20_000_000 }
    data = OpenStruct.new(hash)
    
    p data        # -> <OpenStruct country="Australia" population=20000000>
    

    【讨论】:

      【解决方案2】:

      使用 Ruby OpenStruct 类。它可以满足您的要求,而无需定义此类代码。

      Edit1,示例:

      require 'ostruct'
      
      class Aeroplane < OpenStruct; end
      
      a = Aeroplane.new(:p => :true, :q => :true)
      a.p # => true
      

      【讨论】:

        猜你喜欢
        • 2020-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-24
        • 2014-04-14
        • 2015-05-12
        • 2023-01-19
        • 1970-01-01
        相关资源
        最近更新 更多