2016-04-15 5 views
0

Meine Absicht ist es, benutzerdefinierte Fehler Klassen an verschiedenen Orten für meine Rails-Anwendung zu erstellen, da die meisten Fehler Klassen die gleichen Methoden haben. Ich habe beschlossen, eine YAML-Datei zu erstellen, die alle Informationen aus verschiedenen Fehlerklassen enthält, und ein Klassenfactory-Skript zu verwenden, um alle Klassen in Runtime zu generieren. Hier ist, was ich habe:Pass in Ruby Variable zu einer Klasse Factory Ruby-Skript

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 

die GLOBAL_ERROR_CLASSES von YAML.load geladen und auf ein Objekt gedreht.

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 

* __ Frage ist __ *

Jetzt habe ich andere Dateien wie register_policy, checkout_policy, discount_policy ..etc. Es wäre sehr dupliziert, wenn ich die Klassengenerierung in jeder Richtliniendatei durchführen müsste. Ich frage mich, ob ich den Code so etwas wie dies verkürzen kann:

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 

Was habe ich versucht,

Ich habe versucht, eine .rb Datei im Grunde die Klasse Fabrik Skript Kopieren zu erstellen. Und verwenden Sie eval Methode es in Runtime eval, aber es scheint, dass ich in Variablen in das Skript übergeben können

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

Was soll ich tun?

+0

Setzen Sie Ihre Klassenfabrik in ein Modul und mischen Sie dieses Modul in die Klassen, die die Generation benötigen. –

+1

Lassen Sie den YAML-Ansatz fallen, machen Sie geeignete Klassen. Einfacher zu testen, einfacher zu lesen, eigenständig, weniger Kopfschmerzen. –

Antwort

0

Ich schätze den Aufwand zu vermeiden, sich um jeden Preis zu wiederholen, aber ich finde Ihren Code ziemlich komplex für das Problem, das Sie versuchen zu lösen, nämlich Fehler an Ihre App-Benutzer senden.

Wie wäre es mit der einfacheren Vererbungshierarchie < MyAppError, um den doppelten Code zu vermeiden?

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