2016-04-15 97 views
0

我的意图是在我的Rails应用程序的各个位置创建自定义错误类,因为大多数错误类都具有相同的方法。我决定创建一个YAML文件来包含来自各种错误类的所有信息,并使用类工厂脚本在运行时生成所有类。以下是我有:将ruby变量传递给类工厂ruby脚本

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 

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

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它在运行,但似乎我可以在变量传递到脚本

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

我应该怎么办?

+0

将您的类工厂放在一个模块中,并将该模块混合到需要生成的类中。 –

+1

放弃YAML方法,做适当的类。更容易测试,更易于阅读,自包含,更少的头痛。 –

回答

0

我很欣赏避免不惜一切代价重复自己的努力,但是我发现你的代码对于你要解决的问题来说相当复杂,即向你的应用程序用户发送错误。

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

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 
相关问题