【问题标题】:Rails lib/module with 'class Class' and custom attr_accessor带有“class Class”和自定义 attr_accessor 的 Rails lib/module
【发布时间】:2015-03-11 04:42:30
【问题描述】:

我想像这样制作自己的 attr_accessor:

  class Class
    def attr_accessor_with_onchange_callback(*args, &block)
      raise 'Callback block is required' unless block
      args.each do |arg|
        attr_name = arg.to_s
        define_method(attr_name) do
           self.instance_variable_get("@#{attr_name}")
        end
        define_method("#{attr_name}=") do |argument|
          old_value = self.instance_variable_get("@#{attr_name}")
          if argument != old_value
            self.instance_variable_set("@#{attr_name}", argument)
            self.instance_exec(attr_name, argument, old_value, &block)
          end
        end   
      end
    end
  end

如果我在应用初始化之前将此定义放在config/enviroment.rb 中,它会起作用。

class MyCLass < ActiveRecord::Base
  attr_accessor_with_onchange_callback :some_attr do |attr_name, value, old_value|
  end

但我认为它应该在 lib/ 文件夹中。如果我把这个

module ModelHelpers
  class Class
    def attr_accessor_with_onchange_callback(*args, &block)
      raise 'Callback block is required' unless block
      args.each do |arg|
        attr_name = arg.to_s
        define_method(attr_name) do
           self.instance_variable_get("@#{attr_name}")
        end
        define_method("#{attr_name}=") do |argument|
          old_value = self.instance_variable_get("@#{attr_name}")
          if argument != old_value
            self.instance_variable_set("@#{attr_name}", argument)
            self.instance_exec(attr_name, argument, old_value, &block)
          end
        end   
      end
    end
  end
end

lib/model_helpers.rb 和这个

require 'model_helpers'
class MyCLass < ActiveRecord::Base
  include ModelHelpers
  attr_accessor_with_onchange_callback :some_attr do |attr_name, value, old_value|
end

到 my_class.rb 然后我得到一个错误:undefined method attr_accessor_with_onchange_callback。 我做错了什么?

【问题讨论】:

    标签: ruby-on-rails ruby metaprogramming


    【解决方案1】:

    尝试直接在 ModelHelpers 中定义你的方法 attr_accessor_with_onchange_callback,不使用类 Class。并使用扩展关键字代替包含在类定义中。像这样:

    module ModelHelpers
      def attr_accessor_with_onchange_callback(*args, &block)
    ...
    
    require 'model_helpers'
    class MyCLass < ActiveRecord::Base
      extend ModelHelpers
    

    这是我的例子:

    module ModelHelpers
        def my_method
            puts 'ModelHelpers::my_method called.'
            puts "self is #{self}"
        end
    end
    
    class MyCLass 
      extend ModelHelpers
      my_method
    end
    

    输出是:

    > ruby custom_method_inside_class.rb
    ModelHelpers::my_method called.
    self is MyCLass
    

    【讨论】:

    • 不,同样的错误undefined method。据我所知,它必须在 Class 内,因为它是所有类的新类方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多