Ruby异常好的实践

时间:2017-10-12 22:27:26

标签: ruby-on-rails ruby

这是在Ruby中使用异常的一个很好的做法吗? (如果是object.nil,则使用raise ArgumentError?)

我应该在这里删除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

1 个答案:

答案 0 :(得分: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