Reputation: 4175
Is this a good practice of usage of exceptions in Ruby ? (usage of raise ArgumentError if object.nil?)
Should I delete the ArgumentError here ? Or writing custom exception like 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
Upvotes: 0
Views: 59
Reputation: 2734
As it was suggested in the comments, I would encourage you to use ActiveRecord
validations:
http://guides.rubyonrails.org/active_record_validations.html
Here an example of what you asked in the question:
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
When you create an Order
instance you can perform those validations. An example could be in a controller create action:
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
Upvotes: 2