Skip to content

Commit 73b64d3

Browse files
committed
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 attr-encrypted#216]
1 parent e19445a commit 73b64d3

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

lib/attr_encrypted.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,11 @@ def attr_encrypted(*attributes)
159159
end
160160

161161
define_method("#{attribute}=") do |value|
162-
send("#{encrypted_attribute_name}=", encrypt(attribute, value))
163-
instance_variable_set("@#{attribute}", value)
162+
old_value = instance_variable_get("@#{attribute}")
163+
if old_value.nil? || old_value != value
164+
send("#{encrypted_attribute_name}=", encrypt(attribute, value))
165+
instance_variable_set("@#{attribute}", value)
166+
end
164167
end
165168

166169
define_method("#{attribute}?") do

test/attr_encrypted_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,4 +463,13 @@ def test_should_not_by_default_generate_iv_when_attribute_is_empty
463463
user.with_true_if = nil
464464
assert_nil user.encrypted_with_true_if_iv
465465
end
466+
467+
def test_should_not_generate_iv_if_same_value
468+
user = User.new
469+
assert_nil user.encrypted_email_iv
470+
user.email = 'thing@thing.com'
471+
refute_nil(old_value = user.encrypted_email_iv)
472+
user.email = 'thing@thing.com'
473+
assert_equal old_value, user.encrypted_email_iv
474+
end
466475
end

0 commit comments

Comments
 (0)