From 7e8702bd5418c927a39d8dd72c0adbea522d5663 Mon Sep 17 00:00:00 2001 From: Sean Abrahams Date: Thu, 7 Feb 2019 13:34:15 -0800 Subject: [PATCH] Support ActiveRecord 5.2 --- .travis.yml | 7 +++++ attr_encrypted.gemspec | 3 ++- lib/attr_encrypted/adapters/active_record.rb | 16 +++++++++++- test/active_record_test.rb | 27 +++++++++++++++++++- test/test_helper.rb | 3 ++- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f75b2ede..7b56a02b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,16 +18,21 @@ env: - ACTIVERECORD=4.2.0 - ACTIVERECORD=5.0.0 - ACTIVERECORD=5.1.1 + - ACTIVERECORD=5.2.0 matrix: exclude: - rvm: 2.0 env: ACTIVERECORD=5.0.0 - rvm: 2.0 env: ACTIVERECORD=5.1.1 + - rvm: 2.0 + env: ACTIVERECORD=5.2.0 - rvm: 2.1 env: ACTIVERECORD=5.0.0 - rvm: 2.1 env: ACTIVERECORD=5.1.1 + - rvm: 2.1 + env: ACTIVERECORD=5.2.0 - rvm: 2.4.0 env: ACTIVERECORD=3.0.0 - rvm: 2.4.0 @@ -52,6 +57,8 @@ matrix: env: ACTIVERECORD=5.0.0 - rvm: rbx env: ACTIVERECORD=5.1.1 + - rvm: rbx + env: ACTIVERECORD=5.2.0 allow_failures: - rvm: rbx fast_finish: true diff --git a/attr_encrypted.gemspec b/attr_encrypted.gemspec index 41f96ed9..5f4b8202 100644 --- a/attr_encrypted.gemspec +++ b/attr_encrypted.gemspec @@ -42,6 +42,7 @@ Gem::Specification.new do |s| s.add_development_dependency('rake') s.add_development_dependency('minitest') s.add_development_dependency('sequel') + s.add_development_dependency('pry-byebug') if RUBY_VERSION < '2.1.0' s.add_development_dependency('nokogiri', '< 1.7.0') s.add_development_dependency('public_suffix', '< 3.0.0') @@ -50,7 +51,7 @@ Gem::Specification.new do |s| s.add_development_dependency('activerecord-jdbcsqlite3-adapter') s.add_development_dependency('jdbc-sqlite3', '< 3.8.7') # 3.8.7 is nice and broke else - s.add_development_dependency('sqlite3') + s.add_development_dependency('sqlite3', '~> 1.3.0', '>= 1.3.6') end s.add_development_dependency('dm-sqlite-adapter') s.add_development_dependency('simplecov') diff --git a/lib/attr_encrypted/adapters/active_record.rb b/lib/attr_encrypted/adapters/active_record.rb index fca9343e..fab04c8e 100644 --- a/lib/attr_encrypted/adapters/active_record.rb +++ b/lib/attr_encrypted/adapters/active_record.rb @@ -66,7 +66,7 @@ def attr_encrypted(*attrs) end else define_method("#{attr}_changed?") do - attribute_changed?(attr) + attribute_changed?(attr) end end @@ -75,6 +75,20 @@ def attr_encrypted(*attrs) end define_method("#{attr}_with_dirtiness=") do |value| + ## + # In ActiveRecord 5.2+, due to changes to the way virtual + # attributes are handled, @attributes[attr].value is nil which + # breaks attribute_was. Setting it here returns us to the expected + # behavior. + if ::ActiveRecord::VERSION::STRING >= "5.2" + # This is needed support attribute_was before a record has + # been saved + set_attribute_was(attr, __send__(attr)) if value != __send__(attr) + # This is needed to support attribute_was after a record has + # been saved + @attributes.write_from_user(attr.to_s, value) if value != __send__(attr) + end + ## attribute_will_change!(attr) if value != __send__(attr) __send__("#{attr}_without_dirtiness=", value) end diff --git a/test/active_record_test.rb b/test/active_record_test.rb index 8ec31aea..c0a2f464 100644 --- a/test/active_record_test.rb +++ b/test/active_record_test.rb @@ -126,7 +126,6 @@ class Address < ActiveRecord::Base end class ActiveRecordTest < Minitest::Test - def setup drop_all_tables create_tables @@ -221,6 +220,32 @@ def test_attribute_was_works_when_options_for_old_encrypted_value_are_different_ assert_equal pw.reverse, account.password end + # ActiveRecord 5.2 specific methods + if ::ActiveRecord::VERSION::STRING >= "5.2" + def test_should_create_will_save_change_to_predicate + person = Person.create!(email: 'test@example.com') + refute person.will_save_change_to_email? + person.email = 'test@example.com' + refute person.will_save_change_to_email? + person.email = 'test2@example.com' + assert person.will_save_change_to_email? + end + + def test_should_create_saved_change_to_predicate + person = Person.create!(email: 'test@example.com') + assert person.saved_change_to_email? + person.reload + person.email = 'test@example.com' + refute person.saved_change_to_email? + person.email = nil + refute person.saved_change_to_email? + person.email = 'test2@example.com' + refute person.saved_change_to_email? + person.save + assert person.saved_change_to_email? + end + end + if ::ActiveRecord::VERSION::STRING > "4.0" def test_should_assign_attributes @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false) diff --git a/test/test_helper.rb b/test/test_helper.rb index c352a138..33dcf2d9 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -2,7 +2,8 @@ require 'simplecov' require 'simplecov-rcov' -require "codeclimate-test-reporter" +require 'codeclimate-test-reporter' +require 'pry-byebug' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new( [