Diff Two Hashes And Return Added Removed And Changed Keys In Ruby
When comparing configuration objects, API responses, or form submissions, you often need to know exactly what changed — not just whether the hashes are equal.
Description
This method produces a structured diff between two hashes, categorizing each key difference as added (exists only in new hash), removed (exists only in old hash), or changed (exists in both but values differ). It uses Ruby’s set operations on hash keys to efficiently identify each category in a single pass.
This is especially useful for audit logging, change detection in background jobs, or surfacing what changed inside before/after model callbacks.
Sample input:
old = { name: "Alice", role: "user", age: 30 }
new_data = { name: "Alice", role: "admin", city: "NYC" }
Sample Output:
{
added: { city: "NYC" },
removed: { age: 30 },
changed: { role: ["user", "admin"] }
}
Answer
def hash_diff(old_hash, new_hash)
old_keys = old_hash.keys.to_set
new_keys = new_hash.keys.to_set
{
added: new_hash.slice(*(new_keys - old_keys)),
removed: old_hash.slice(*(old_keys - new_keys)),
changed: (old_keys & new_keys).each_with_object({}) do |k, diff|
diff[k] = [old_hash[k], new_hash[k]] if old_hash[k] != new_hash[k]
end
}
end
Check viewARU - Brand Newsletter!
Newsletter to DEVs by DEVs - boost your Personal Brand & career! 🚀