「作成」→「更新」→「空更新」とした場合の変化。
 作成 create(foo: "a")
| method | before_save | after_save | 
| will_save_change_to_attribute?(:foo) | true | false | 
| attribute_change_to_be_saved(:foo) | [nil, "a"] | nil | 
| attribute_in_database(:foo) | nil | "a" | 
| changes_to_save | {"foo"=>[nil, "a"]} | {} | 
| has_changes_to_save? | true | false | 
| changed_attribute_names_to_save | ["foo"] | [] | 
| attributes_in_database | {"foo"=>nil} | {} | 
| saved_change_to_attribute?(:foo) | false | true | 
| saved_change_to_attribute(:foo) | nil | [nil, "a"] | 
| attribute_before_last_save(:foo) | nil | nil | 
| saved_changes | {} | {"id"=>[nil, 1], "foo"=>[nil, "a"]} | 
| saved_changes? | false | true | 
 更新 update(foo: "b")
| method | before_save | after_save | 
| will_save_change_to_attribute?(:foo) | true | false | 
| attribute_change_to_be_saved(:foo) | ["a", "b"] | nil | 
| attribute_in_database(:foo) | "a" | "b" | 
| changes_to_save | {"foo"=>["a", "b"]} | {} | 
| has_changes_to_save? | true | false | 
| changed_attribute_names_to_save | ["foo"] | [] | 
| attributes_in_database | {"foo"=>"a"} | {} | 
| saved_change_to_attribute?(:foo) | true | true | 
| saved_change_to_attribute(:foo) | nil | ["a", "b"] | 
| attribute_before_last_save(:foo) | nil | "a" | 
| saved_changes | {} | {"foo"=>["a", "b"]} | 
| saved_changes? | false | true | 
 空更新 update({})
| method | before_save | after_save | 
| will_save_change_to_attribute?(:foo) | false | false | 
| attribute_change_to_be_saved(:foo) | nil | nil | 
| attribute_in_database(:foo) | "b" | "b" | 
| changes_to_save | {} | {} | 
| has_changes_to_save? | false | false | 
| changed_attribute_names_to_save | [] | [] | 
| attributes_in_database | {} | {} | 
| saved_change_to_attribute?(:foo) | false | false | 
| saved_change_to_attribute(:foo) | nil | nil | 
| attribute_before_last_save(:foo) | nil | "b" | 
| saved_changes | {} | {} | 
| saved_changes? | false | false | 
 検証用のコード
require "active_record"
ActiveRecord::VERSION::STRING             
ActiveSupport::LogSubscriber.colorize_logging = false
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
  create_table :users do |t|
    t.string :foo
  end
end
class User < ActiveRecord::Base
  before_save do
    will_save_change_to_attribute?(:foo)  
    attribute_change_to_be_saved(:foo)    
    attribute_in_database(:foo)           
    changes_to_save                       
    has_changes_to_save?                  
    changed_attribute_names_to_save       
    attributes_in_database                
    saved_change_to_attribute?(:foo)      
    saved_change_to_attribute(:foo)       
    attribute_before_last_save(:foo)      
    saved_changes                         
    saved_changes?                        
  end
  after_save do
    will_save_change_to_attribute?(:foo)  
    attribute_change_to_be_saved(:foo)    
    attribute_in_database(:foo)           
    changes_to_save                       
    has_changes_to_save?                  
    changed_attribute_names_to_save       
    attributes_in_database                
    saved_change_to_attribute?(:foo)      
    saved_change_to_attribute(:foo)       
    attribute_before_last_save(:foo)      
    saved_changes                         
    saved_changes?                        
  end
end
user = User.create!(foo: "a")             
user.reload                               
user.update!(foo: "b")                    
user.reload                               
user.update!({})                          
Discussion