ar_transaction_changes 1.1.2 → 1.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8512832019c33caf8bd9bb39796f2db6b6e8ce74
4
- data.tar.gz: 05f8382a08442778dc3a9eb3fc4d9f573c83969d
2
+ SHA256:
3
+ metadata.gz: 1b75ccc7bc393e60284a26e6077bdfc48e8032b52780770f0b762f292a6a3393
4
+ data.tar.gz: 2a048448c70283320792559fd7f7ae90d339384fda9fa3b9d437abf2607fd701
5
5
  SHA512:
6
- metadata.gz: 258b699e07a4dcc3bbce95dce4991f5916569f94764eb3c66fb2627fb12e3f98520eb0663a57986cf868f37eef0703f013a9f6d4c73e9337682d67b8e29b6de3
7
- data.tar.gz: e8b2912cc3fd090905493e6d0230da91fe08251cfea9cb1edebe93ab1eaa78619d667947d81689443f6a0d56158da4db545d2583ec632b83e76b65bfeec935f3
6
+ metadata.gz: f3148c75a2a2bebc626451d1cbfbb7263cb1e39a56571af89761dc1f5b96a3a988de2a97ee2bef546744765f2b3eb569de77ce45fea5e7da1289821231435076
7
+ data.tar.gz: e21dff998d73c00ee6f6b8b7d92d9814412bf3421b8dc009e41429b7fc33e014cd9cd4f01d05288bc5009fc530749628de7d19c6e97973c53a3ddd37bc8f9cd0
@@ -1,22 +1,17 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
 
4
- rvm:
5
- - 2.2.5
6
- - 2.3.1
7
-
8
- gemfile:
9
- - Gemfile.rails42
10
- - Gemfile.rails50
11
- - Gemfile.rails51
12
-
13
- matrix:
4
+ jobs:
14
5
  include:
15
- - rvm: 2.1.9
16
- gemfile: Gemfile.rails42
6
+ - name: "Minimum supported versions"
7
+ rvm: 2.4
8
+ gemfile: Gemfile.rails52
9
+ - name: "Latest released versions"
10
+ rvm: 2.7
11
+ gemfile: Gemfile
12
+ - name: "Rails master branch"
13
+ rvm: 2.7
14
+ gemfile: Gemfile.rails_head
17
15
 
18
16
  services:
19
17
  - mysql
20
-
21
- before_script:
22
- - mysql -e 'create database ar_transaction_changes_test'
@@ -1,5 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "rails", "~> 4.2.0"
3
+ gem 'activerecord', '~> 5.2.0'
4
4
 
5
5
  gemspec
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activerecord', github: 'rails/rails'
4
+
5
+ gemspec
data/README.md CHANGED
@@ -44,6 +44,19 @@ class User < ActiveRecord::Base
44
44
  end
45
45
  ```
46
46
 
47
+ ## Important Notes
48
+
49
+ `ar_transaction_changes` may have conflict with another gems who modify
50
+ `active_record#write_attribute` method, e.g. `globalize` gem
51
+
52
+ the workaround is by requiring this gem first, for example:
53
+
54
+ ```ruby
55
+ gem 'ar_transaction_changes', require: false
56
+ gem 'globalize', require: ['ar_transaction_changes', 'globalize']
57
+
58
+ ```
59
+
47
60
  ## Contributing
48
61
 
49
62
  1. Fork it
@@ -11,13 +11,14 @@ Gem::Specification.new do |gem|
11
11
  gem.description = %q{Solves the problem of trying to get all the changes to an object during a transaction in an after_commit callbacks.}
12
12
  gem.summary = %q{Store transaction changes for active record objects}
13
13
  gem.homepage = "https://github.com/dylanahsmith/ar_transaction_changes"
14
+ gem.license = "MIT"
14
15
 
15
16
  gem.files = `git ls-files`.split($/)
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
19
  gem.require_paths = ["lib"]
19
20
 
20
- gem.add_dependency "activerecord", ">= 4.2.4", "< 6.0"
21
+ gem.add_dependency "activerecord", ">= 5.2.0"
21
22
 
22
23
  gem.add_development_dependency("rake")
23
24
  gem.add_development_dependency("mysql2")
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "ar_transaction_changes/version"
4
+ require "active_record"
2
5
 
3
6
  module ArTransactionChanges
4
7
  def _run_commit_callbacks
@@ -17,13 +20,52 @@ module ArTransactionChanges
17
20
  @transaction_changed_attributes ||= HashWithIndifferentAccess.new
18
21
  end
19
22
 
20
- def write_attribute(attr_name, value) # override
23
+ def _write_attribute(attr_name, value)
24
+ _store_transaction_changed_attributes(attr_name) do
25
+ super(attr_name, value)
26
+ end
27
+ end
28
+
29
+ if ActiveRecord.version >= Gem::Version.new('6.1.0.alpha')
30
+ def write_attribute(attr_name, value)
31
+ _store_transaction_changed_attributes(attr_name) do
32
+ super(attr_name, value)
33
+ end
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def _store_transaction_changed_attributes(attr_name)
21
40
  attr_name = attr_name.to_s
22
- old_value = attributes[attr_name]
23
- ret = super
24
- unless transaction_changed_attributes.key?(attr_name) || value == old_value
25
- transaction_changed_attributes[attr_name] = old_value
41
+ old_value = _read_attribute_for_transaction(attr_name)
42
+ ret = yield
43
+ new_value = _read_attribute_for_transaction(attr_name)
44
+ unless transaction_changed_attributes.key?(attr_name) || new_value == old_value
45
+ attribute = @attributes[attr_name]
46
+ transaction_changed_attributes[attr_name] = if attribute.type.is_a?(::ActiveRecord::Type::Serialized)
47
+ attribute.type.deserialize(old_value)
48
+ else
49
+ old_value
50
+ end
51
+ transaction_changed_attributes
26
52
  end
27
53
  ret
28
54
  end
55
+
56
+ def _read_attribute_for_transaction(attr_name)
57
+ attribute = @attributes[attr_name]
58
+ # Avoid causing an earlier memoized type cast of mutable serialized user values,
59
+ # since could prevent mutations of that user value from affecting the attribute value
60
+ # that would affect it without using this library.
61
+ if attribute.type.is_a?(::ActiveRecord::Type::Serialized)
62
+ if attribute.came_from_user?
63
+ attribute.type.serialize(attribute.value_before_type_cast)
64
+ else
65
+ attribute.value_before_type_cast
66
+ end
67
+ else
68
+ _read_attribute(attr_name)
69
+ end
70
+ end
29
71
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArTransactionChanges
2
- VERSION = "1.1.2"
4
+ VERSION = "1.1.7"
3
5
  end
@@ -1,6 +1,16 @@
1
1
  class User < ActiveRecord::Base
2
2
  include ArTransactionChanges
3
3
 
4
+ class ConnectionDetails
5
+ attr_accessor :client_ip
6
+
7
+ def initialize(client_ip:)
8
+ @client_ip = client_ip
9
+ end
10
+ end
11
+
12
+ serialize :connection_details, Array
13
+
4
14
  attr_accessor :stored_transaction_changes
5
15
 
6
16
  after_commit :store_transaction_changes_for_tests
@@ -1,20 +1,25 @@
1
- ENV["RAILS_ENV"] = "test"
2
1
  require 'pathname'
3
2
  require 'yaml'
4
- require 'active_record'
5
3
  require 'ar_transaction_changes'
6
4
  require 'minitest/autorun'
7
5
 
6
+ ENV["RAILS_ENV"] = "test"
7
+
8
8
  test_dir = Pathname.new(File.dirname(__FILE__))
9
9
  config_filename = test_dir.join("database.yml").exist? ? "database.yml" : "database.yml.default"
10
10
  database_yml = YAML.load(test_dir.join(config_filename).read)
11
- ActiveRecord::Base.establish_connection database_yml['test']
11
+ database_config = database_yml.fetch("test")
12
+
13
+ ActiveRecord::Base.establish_connection(database_config.except("database"))
14
+ ActiveRecord::Base.connection.recreate_database(database_config.fetch("database"))
15
+ ActiveRecord::Base.establish_connection(database_config)
12
16
 
13
17
  ActiveRecord::Base.connection.tap do |db|
14
- db.drop_table(:users) if db.table_exists?(:users)
15
18
  db.create_table(:users) do |t|
16
19
  t.string :name
17
20
  t.string :occupation
21
+ t.integer :age
22
+ t.text :connection_details
18
23
  t.timestamps null: false
19
24
  end
20
25
  end
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class TransactionChangesTest < MiniTest::Unit::TestCase
4
4
  def setup
5
- @user = User.new(:name => "Dylan", :occupation => "Developer")
5
+ @user = User.new(:name => "Dylan", :occupation => "Developer", age: 20)
6
6
  @user.save!
7
7
  @user.stored_transaction_changes = nil
8
8
  end
@@ -23,6 +23,13 @@ class TransactionChangesTest < MiniTest::Unit::TestCase
23
23
  assert_equal ["Dylan", "Dillon"], @user.stored_transaction_changes["name"]
24
24
  end
25
25
 
26
+ def test_transaction_changes_for_updating_attribute
27
+ @user[:name] = "Dillon"
28
+ @user.save!
29
+
30
+ assert_equal ["Dylan", "Dillon"], @user.stored_transaction_changes["name"]
31
+ end
32
+
26
33
  def test_transaction_changes_for_double_save
27
34
  @user.transaction do
28
35
  @user.name = "Dillon"
@@ -67,7 +74,7 @@ class TransactionChangesTest < MiniTest::Unit::TestCase
67
74
  end
68
75
 
69
76
  def test_transaction_changes_for_changing_updated_at
70
- @user.update_attributes!(updated_at: Time.now - 1.second)
77
+ @user.update!(updated_at: Time.now - 1.second)
71
78
  old_updated_at = @user.updated_at
72
79
  @user.stored_transaction_changes = nil
73
80
 
@@ -78,7 +85,7 @@ class TransactionChangesTest < MiniTest::Unit::TestCase
78
85
  end
79
86
 
80
87
  def test_transaction_changes_for_touch
81
- @user.update_attributes!(updated_at: Time.now - 1.second)
88
+ @user.update!(updated_at: Time.now - 1.second)
82
89
  old_updated_at = @user.updated_at
83
90
  @user.stored_transaction_changes = nil
84
91
 
@@ -94,4 +101,29 @@ class TransactionChangesTest < MiniTest::Unit::TestCase
94
101
  end
95
102
  refute @user.stored_transaction_changes["name"]
96
103
  end
104
+
105
+ def test_transaction_changes_type_cast
106
+ # "20" will be converted to 20 by read_attribute https://apidock.com/rails/ActiveRecord/AttributeMethods/read_attribute
107
+ @user.transaction do
108
+ @user.age = "20"
109
+ @user.save!
110
+ end
111
+ assert_empty @user.stored_transaction_changes
112
+ end
113
+
114
+ def test_serialized_attributes_value
115
+ @user.connection_details = [User::ConnectionDetails.new(client_ip: '1.1.1.1')]
116
+ @user.save!
117
+ old_value, new_value = @user.stored_transaction_changes['connection_details']
118
+ assert_equal([], old_value)
119
+ assert_equal(['1.1.1.1'], new_value.map(&:client_ip))
120
+ end
121
+
122
+ def test_serialized_attributes_mutation
123
+ details = User::ConnectionDetails.new(client_ip: '1.1.1.1')
124
+ @user.connection_details = [details]
125
+ details.client_ip = '2.2.2.2'
126
+ @user.save!
127
+ assert_equal '2.2.2.2', @user.connection_details.first.client_ip
128
+ end
97
129
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_transaction_changes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Thacker-Smith
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-12 00:00:00.000000000 Z
11
+ date: 2020-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.2.4
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '6.0'
19
+ version: 5.2.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 4.2.4
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '6.0'
26
+ version: 5.2.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rake
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -69,9 +63,8 @@ files:
69
63
  - ".gitignore"
70
64
  - ".travis.yml"
71
65
  - Gemfile
72
- - Gemfile.rails42
73
- - Gemfile.rails50
74
- - Gemfile.rails51
66
+ - Gemfile.rails52
67
+ - Gemfile.rails_head
75
68
  - LICENSE.txt
76
69
  - README.md
77
70
  - Rakefile
@@ -83,9 +76,10 @@ files:
83
76
  - test/test_helper.rb
84
77
  - test/transaction_changes_test.rb
85
78
  homepage: https://github.com/dylanahsmith/ar_transaction_changes
86
- licenses: []
79
+ licenses:
80
+ - MIT
87
81
  metadata: {}
88
- post_install_message:
82
+ post_install_message:
89
83
  rdoc_options: []
90
84
  require_paths:
91
85
  - lib
@@ -100,9 +94,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
94
  - !ruby/object:Gem::Version
101
95
  version: '0'
102
96
  requirements: []
103
- rubyforge_project:
104
- rubygems_version: 2.6.10
105
- signing_key:
97
+ rubygems_version: 3.1.2
98
+ signing_key:
106
99
  specification_version: 4
107
100
  summary: Store transaction changes for active record objects
108
101
  test_files:
@@ -1,5 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "rails", "~> 5.0.0"
4
-
5
- gemspec
@@ -1,5 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "rails", "~> 5.1.0.rc1"
4
-
5
- gemspec