2017-10-12 6 views
0

これはRubyでの例外の使用の良い習慣ですか? (object.nilの場合raise ArgumentErrorの使用法)Rubyの例外の良い説明

ここでArgumentErrorを削除してください。 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

これは本当にレールですか?もしそうなら、なぜモデルバリデーションを使用しないのですか? –

+3

ただサイドノートですが、 'guests = options.has_key?(:guests)? options [:guests]:nil'は不要です。不明なキーのハッシュ値はすでにゼロになっています。あなたは 'guests = options [:guests]' –

+3

と言うことができます。私の意見ではエラーを発生させる代わりにバリデーションを使うべきです。私はそれがいくつかのリファクタリングを取ると信じているので、申し訳ありませんあなたのための答えを持っていません。 – vee

答えて

2

それはコメントで示唆されたように、私はActiveRecord検証に使用することをお勧めします:ここで

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

あなたが質問に尋ねたものの例:

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 

Orderインスタンスを作成すると、それらの検証を実行できます。コントローラー作成アクションの例があります:

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 
関連する問題