save()是返回true或false的,可据此来决定程序如何走向,渲染什么模板

if order.save
  # all OK
else
  # validation failed
end


此种做法通常适用于“会在view中展示报错给user”。而save!在验证失败时,则是抛RecordInvalid,可用它来触发transaction的rollback

begin
  order.save!
rescue RecordInvalid => error
  # validation failed
end


一般来说,在没有手写transaction时,用non-bang就可以

源码如下

module ActiveRecord
  module Validations
    extend ActiveSupport::Concern
    include ActiveModel::Validations

    def save(options={})
      perform_validations(options) ? super : false
    end

    def save!(options={})
      perform_validations(options) ? super : raise_validation_error
    end

    def valid?(context = nil)
      context ||= default_validation_context
      output = super(context)
      errors.empty? && output
    end

    alias_method :validate, :valid?

  protected

    def default_validation_context
      new_record? ? :create : :update
    end

    def raise_validation_error
      raise(RecordInvalid.new(self))
    end

    def perform_validations(options={}) # :nodoc:
      options[:validate] == false || valid?(options[:context])
    end
  end
end