From 73b64d35985990d8bd231c8ad59bd9ce69f5431b Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Wed, 6 Dec 2017 09:55:13 -0500 Subject: [PATCH] Don't change iv field when value is the same ``` user = User.new(name: 'hi') user.name = 'hi' ``` That code would generate two different ivs. At first look that is not an issue, but when using attr_encrypted combined with ActiveRecord this could impose some issues. Like extra writes to the db. Also, marking some attributes as dirty, when they were actually not changed. [fixes #216] --- lib/attr_encrypted.rb | 7 +++++-- test/attr_encrypted_test.rb | 9 +++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/attr_encrypted.rb b/lib/attr_encrypted.rb index 3bfa87c9..8e8e3943 100644 --- a/lib/attr_encrypted.rb +++ b/lib/attr_encrypted.rb @@ -159,8 +159,11 @@ def attr_encrypted(*attributes) end define_method("#{attribute}=") do |value| - send("#{encrypted_attribute_name}=", encrypt(attribute, value)) - instance_variable_set("@#{attribute}", value) + old_value = instance_variable_get("@#{attribute}") + if old_value.nil? || old_value != value + send("#{encrypted_attribute_name}=", encrypt(attribute, value)) + instance_variable_set("@#{attribute}", value) + end end define_method("#{attribute}?") do diff --git a/test/attr_encrypted_test.rb b/test/attr_encrypted_test.rb index 0afbd37c..6b4c5335 100644 --- a/test/attr_encrypted_test.rb +++ b/test/attr_encrypted_test.rb @@ -463,4 +463,13 @@ def test_should_not_by_default_generate_iv_when_attribute_is_empty user.with_true_if = nil assert_nil user.encrypted_with_true_if_iv end + + def test_should_not_generate_iv_if_same_value + user = User.new + assert_nil user.encrypted_email_iv + user.email = 'thing@thing.com' + refute_nil(old_value = user.encrypted_email_iv) + user.email = 'thing@thing.com' + assert_equal old_value, user.encrypted_email_iv + end end