2017-10-12 3 views
0

Ist dies eine gute Praxis der Verwendung von Ausnahmen in Ruby? (Verwendung von raise ArgumentError falls object.nil?)Ruby Ausnahme gute Praxis

Soll ich hier den ArgumentError löschen? Oder benutzerdefinierte Ausnahme schreiben wie ProductNilError, QuantityMustBeMoreThanZeroError?

def create_order(product, options = { quantity: 1, guests: nil, confirmation_needed: false }) 
    raise ArgumentError, 'product is nil' if product.nil? 

    guests = options.has_key?(:guests) ? options[:guests] : nil 
    quantity = options.has_key?(:quantity) ? options[:quantity] : nil 
    confirmation_needed = options.has_key?(:confirmation_needed) ? options[:confirmation_needed] : nil 

    raise ArgumentError, 'quantity must be > 0' if quantity.nil? || quantity < 0 || quantity == 0 
    raise ArgumentError, 'product of beneficiary_type need guests' if product.is_a_beneficiary_type? && guests.nil? 
    raise ArgumentError, 'guests do not respond_to each (not an array)' if !guests.nil? && !guests.respond_to?(:each) 
    raise ArgumentError, 'product of quantity_type do not need guests' if product.is_a_quantity_type? && !guests.nil? 

    begin 
     order = build_order(guests, product) 
     debit_stock(quantity) 
     pay(order, product, quantity) 
     confirm_order(order) 
    ensure 
     rollback(order, quantity) 
    end 
    end 
+2

Ist das wirklich Schienen? Wenn ja, warum nicht Modellvalidierungen verwenden? –

+3

nur eine Randnotiz, aber 'guests = options.has_key? (: Gäste)? Optionen [: Gäste]: Null ist unnötig. Ein Hash-Wert bei einem unbekannten Schlüssel ist bereits Null, Sie können einfach sagen: Gäste = Optionen [: Gäste] ' –

+3

Validierungen sollten meiner Meinung nach verwendet werden, anstatt Fehler zu erhöhen. Entschuldige, ich habe keine Antwort für dich, weil ich glaube, dass es etwas Refactoring braucht. – vee

Antwort

2

Wie es in den Kommentaren vorgeschlagen wurde, würde ich Sie ermutigen, ActiveRecord Validierungen zu verwenden:

http://guides.rubyonrails.org/active_record_validations.html

Hier ist ein Beispiel dafür, was man in der Frage gestellt:

class Order < ActiveRecord::Base 
    validates :product, presence: true 
    validates :quantity, numericality: { greater_than: 0 } 
    validate :beneficiary_type 

    def beneficiary_type 
    return true unless product.is_a_beneficiary_type? && guests.nil? 
    errors.add(:guests, 'product of beneficiary_type need guests.') 
    end 
end 

Wenn Sie eine Order Instanz erstellen, können Sie diese Validierungen durchführen. Ein Beispiel könnte in einem Controller erstellen Aktion sein:

def create 
    permitted = permitted_params # permit some params 
    @order.new(permitted) 
    if @order.valid? 
    @oder.save! 
    flash[:success] = "Order #{@order.id} has been created!" 
    redirect_to action: :index 
    else 
    render action: :new 
    end 
end