In my Purchase model, I have a method that calculates the tax:
def calculate_tax
  if self.shipping_address.state == State.new_york
    corresponding_tax = Tax.find_by(zip_code: self.shipping_address.zip_code, state_id: self.shipping_address.state_id)
    if corresponding_tax
      self.tax = corresponding_tax.rate * (self.subtotal + shipping)
    else
      #HERE !!!
      self.errors[:base] << "The zip code you have entered is invalid."
      puts "errors = #{self.errors.full_messages}" #<-- this prints out the error in my log, so I know it's being run
    end
  else
    self.tax = 0.00
  end
end
This method is being called within this method:
def update_all_fees!
  calculate_subtotal
  calculate_shipping
  calculate_tax #<-- being called here
  calculate_total
  save!
end
However, save! is saving the record successfully. Shouldn't it be throwing an exception? How would I make it so that save! fails when calculate_tax is in the second else block?
You can add custom validation methods with the validate directive. Here's may take on the code you posted:
class Purchase < ActiveRecord::Base
  validate :new_york_needs_tax_record
  def update_all_fees!
    calculate_subtotal
    calculate_shipping
    calculate_tax
    calculate_total
    save!
  end
  private
  def calculate_tax
    if ships_to_new_york? && corresponding_tax
      self.tax = corresponding_tax.rate * (self.subtotal + shipping)
    elsif !ships_to_new_york?
      self.tax = 0.00
    else
      self.tax = nil
    end
  end
  def ships_to_new_york?
    self.shipping_address.state == State.new_york
  end
  def corresponding_tax
    Tax.find_by(zip_code: self.shipping_address.zip_code, state_id: self.shipping_address.state_id)
  end
  def new_york_need_tax_record
    if ships_to_new_york?  && !corresponding_tax
      self.errors[:base] << "The zip code you have entered is invalid."
    end
  end
end
                        Edited for historical reasons. The first response didn't cover all scenarios.
But if you need to raise the error if there are any just do:
validate :taxes_scenario
def taxes_scenario
  [Add any clause here that makes your scenario invalid]
end
So you can validate the taxes scenario and made sure your error is added properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With