将ruby变量传递给类工厂ruby脚本

时间:2016-04-15 06:44:49

标签: ruby-on-rails ruby

我的目的是为我的Rails应用程序在各个地方创建自定义错误类,因为大多数错误类都有相同的方法。我决定创建一个YAML文件来包含来自各种错误类的所有信息,并使用类工厂脚本在运行时生成所有类。这就是我所拥有的:

chat_policy.rb

class ChatPolicy; ... end

class ChatPolicy::Error < StandardError
  ERROR_CLASSES = GLOBAL_ERROR_CLASSES['chat_policy']
  ERROR_CLASSES.each do |cls|
  const_set(cls['class_name'], Class.new(ChatPolicy::Error) {
    attr_reader :object

    def initialize(object)
        @object = object
    end

    define_method(:message) do
        cls['message']
    end

    define_method(:code) do
        cls['code']
    end
  })
end

从YAML.load加载GLOBAL_ERROR_CLASSES并转向对象。

error_classes.yml

chat_policy:
- class_name: UserBlacklisted
  message: You are not allowed to do this
  code: ECP01
- class_name: UserSuspended
  message: You are not allowed to do this
  code: ECP02
- class_name: UserNotEligibleToRent
  message: You are not allowed to do this
  code: ECP03
- class_name: MembershipTierNotAllowed
  message: You are not allowed to do this
  code: ECP04

* __问题是__ *

现在我有其他文件,例如register_policycheckout_policydiscount_policy ..等。如果我必须在每个策略文件中进行类生成,那将是非常重复的。我想知道我是否可以将代码缩短为:

chat_policy_intended.rb

class ChatPolicy::Error < StandardError
  ERROR_CLASSES = GLOBAL_ERROR_CLASSES['chat_policy']
  error_class_factory(ChatPolicy::Error, ERROR_CLASSES)
end

discount_policy_intended.rb

class DiscountPolicy::Error < StandardError
  ERROR_CLASSES = GLOBAL_ERROR_CLASSES['discount_policy']
  error_class_factory(DiscountPolicy::Error, ERROR_CLASSES)
end

error_clas_factory.rb

ERROR_CLASSES.each do |cls|
const_set(cls['class_name'], Class.new(/*class_variable*/) {
    attr_reader :object

    def initialize(object)
        @object = object
    end

    define_method(:message) do
        cls['message']
    end

    define_method(:code) do
        cls['code']
    end
})
end

我尝试了什么

我试图创建一个基本上复制类工厂脚本的.rb文件。并使用eval方法在运行时评估它,但似乎我可以将变量传入脚本

eval File.read(File.join(Rails.root, 'lib', 'evals', 'error_class_generator.rb'))

我该怎么办?

1 个答案:

答案 0 :(得分:0)

我感谢您不惜一切代价避免重复自己的努力,但我发现您的代码对于您尝试解决的问题非常复杂,即向您的应用用户发送错误。

如何坚持更简单的< MyAppError继承层次结构以避免重复的代码?

class MyAppError < StandardError
  attr_reader :object

  def message(message)
    # does stuff
  end

  def code(code)
    # also does stuff
  end
end

class ChatPolicyError < MyAppError
  def message(message)
    '[CHAT POLICY]' + super
  end
end

class UserBlacklisted < ChatPolicyError
  def message(message)
    # Does stuff too

    super
  end
end

[...] # You get the idea