Rails lib/module 'class Class' 和自定义 attr_accessor

Rails lib/module with 'class Class' and custom attr_accessor

我想像这样制作自己的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。 我做错了什么?

尝试直接在 ModelHelpers 中定义您的方法 attr_accessor_with_onchange_callback,而不是 class Class。并使用 extend 关键字代替 include inside class defenition。像这样:

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