Rails:添加错误[:base]不会使记录无效?

时间:2014-06-10 19:43:07

标签: ruby-on-rails

在我的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块中时失败了吗?

3 个答案:

答案 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!应该在模型验证失败时自动吐出错误