在我的Purchase
模型中,我有一种计算税收的方法:
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
在此方法中调用此方法:
def update_all_fees!
calculate_subtotal
calculate_shipping
calculate_tax #<-- being called here
calculate_total
save!
end
但是,save!
正在成功保存记录。不应该抛出异常吗?我怎么能这样保存! calculate_tax在第二个else
块中时失败了吗?
答案 0 :(得分:1)
作为对您的问题的回答,添加错误不会使记录无效。但如果有任何问题需要提出错误:
before_save:check_errors
def check_errors
raise RecordInvalid.new(self) if self.errors.any?
end
这将检查.save调用之前添加的错误。
答案 1 :(得分:1)
您可以使用validate
指令添加自定义验证方法。这里可以采用您发布的代码:
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
答案 2 :(得分:0)
只是在错误列表中添加错误不会使记录失败。您必须设置所谓的“验证”。有一些关于它的精彩指南here应该可以帮助你完成整个过程。
例如,您可能希望在Tax模型中添加以下验证:
validates :zip_code, presence: true, numericality: true
一旦设置了验证,save!
应该在模型验证失败时自动吐出错误