ar_transaction_changes 1.1.8 → 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41a85de7f78cb23d9af300f5279a909db5ecab9b3e02bca9cf2ecd4703062b8b
4
- data.tar.gz: cc04e7f4c6e884d4db4fe94c84b8a8ef55871613c0b0d737f9956a5f69d3ebcf
3
+ metadata.gz: 714d24f3fc939b5ab4170bd5863573aea0b5f9f918d3494f51656096579d0cc6
4
+ data.tar.gz: 62d4814dccd3e3f5623958e1182ba8654eca9d37cc01bf986cfa09527fc5b6b5
5
5
  SHA512:
6
- metadata.gz: 4fde634868ccbb2518edbde7841bce8ca6745a41c6ef398d1d20ce55bae6a7eefb9c35689ebecadd3ef8246200a6034bc202960457f42e430a351c56b7ef0742
7
- data.tar.gz: d14df655313155febb0c769a2852efc8c1ce4888cfbaa05ea362ecdb3a1219bc98051b5da1b3583dd8add30ff40a6ea52f0a6ac86198cb54a4d7208520daecb4
6
+ metadata.gz: 1a77baf0fd44d182e407c79ae17499933aa0a85aa1a9d2c7be3c4b1df2a0a6bee34a4d18d10bb82a5aea3b45aaa65dfde4d6254bf49b5aa8abb2dd293900b6ac
7
+ data.tar.gz: ab7fd9f52be45e78f6911159cb7c472ac9d78151891b1968bfcf1629ee97e65a944ef71178c5b5411f935b680d5a460f99f6884c3d8ce08aad6274b882b175f5
@@ -0,0 +1,26 @@
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
3
+ {
4
+ "name": "Ruby",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ "image": "ghcr.io/rails/devcontainer/images/ruby:3.4.7",
7
+ "features": {
8
+ "ghcr.io/devcontainers/features/github-cli:1": {},
9
+ "ghcr.io/rails/devcontainer/features/mysql-client:1": {}
10
+ }
11
+
12
+ // Features to add to the dev container. More info: https://containers.dev/features.
13
+ // "features": {},
14
+
15
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
16
+ // "forwardPorts": [],
17
+
18
+ // Use 'postCreateCommand' to run commands after the container is created.
19
+ // "postCreateCommand": "ruby --version",
20
+
21
+ // Configure tool-specific properties.
22
+ // "customizations": {},
23
+
24
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
25
+ // "remoteUser": "root"
26
+ }
@@ -6,42 +6,83 @@ on:
6
6
  types: [opened, synchronize]
7
7
 
8
8
  jobs:
9
- build:
10
- if: github.event_name == 'push' || github.event.pull_request.head.repo.owner.login != 'dylanahsmith'
11
-
9
+ test:
12
10
  runs-on: ubuntu-latest
13
11
 
14
12
  strategy:
13
+ fail-fast: false
15
14
  matrix:
16
- entry:
17
- - name: 'Minimum supported'
18
- ruby: 2.4
19
- gemfile: Gemfile.rails52
20
- - name: "Latest released versions"
21
- ruby: 3.0
22
- gemfile: Gemfile
23
- - name: "Rails main branch"
24
- ruby: 3.0
25
- gemfile: Gemfile.rails_head
26
-
27
- name: ${{ matrix.entry.name }}
15
+ ruby: ['3.2', '3.3', '3.4']
16
+ rails: ['7.0', '7.1', '7.2', '8.0']
17
+ exclude:
18
+ # Rails 7.0 requires Ruby < 3.4
19
+ - ruby: '3.4'
20
+ rails: '7.0'
21
+
22
+ name: Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }}
28
23
 
29
24
  env:
30
- BUNDLE_GEMFILE: ${{ matrix.entry.gemfile }}
25
+ BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.rails }}.gemfile
31
26
 
32
27
  steps:
33
28
  - name: Install required packages
34
29
  run: |
35
30
  sudo apt-get update
36
31
  sudo apt-get -y install libsqlite3-dev
37
- - uses: actions/checkout@v2
32
+ - uses: actions/checkout@v3
38
33
  - name: Set up Ruby
39
34
  uses: ruby/setup-ruby@v1
40
35
  with:
41
- ruby-version: ${{ matrix.entry.ruby }}
42
- - name: Install bundler and gems
36
+ ruby-version: ${{ matrix.ruby }}
37
+ bundler-cache: true
38
+ - name: Run tests
39
+ run: bundle exec rake
40
+
41
+ test-head:
42
+ runs-on: ubuntu-latest
43
+ continue-on-error: true
44
+
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ ruby: ['3.2', '3.3', '3.4']
49
+
50
+ name: Ruby ${{ matrix.ruby }} / Rails head
51
+
52
+ env:
53
+ BUNDLE_GEMFILE: gemfiles/rails_head.gemfile
54
+
55
+ steps:
56
+ - name: Install required packages
43
57
  run: |
44
- gem install bundler
45
- bundle install --jobs 4 --retry 3
58
+ sudo apt-get update
59
+ sudo apt-get -y install libsqlite3-dev
60
+ - uses: actions/checkout@v3
61
+ - name: Set up Ruby
62
+ uses: ruby/setup-ruby@v1
63
+ with:
64
+ ruby-version: ${{ matrix.ruby }}
65
+ bundler-cache: true
46
66
  - name: Run tests
47
67
  run: bundle exec rake
68
+
69
+ ci-summary:
70
+ runs-on: ubuntu-latest
71
+ needs: [test, test-head]
72
+ if: always()
73
+
74
+ name: CI Summary
75
+
76
+ steps:
77
+ - name: Check test results
78
+ run: |
79
+ if [ "${{ needs.test.result }}" != "success" ]; then
80
+ echo "❌ Required tests failed"
81
+ exit 1
82
+ fi
83
+ echo "✅ All required tests passed"
84
+ if [ "${{ needs.test-head.result }}" != "success" ]; then
85
+ echo "⚠️ Rails head tests failed (non-blocking)"
86
+ else
87
+ echo "✅ Rails head tests passed"
88
+ fi
@@ -0,0 +1,26 @@
1
+ name: Release Gem
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ release:
9
+ permissions:
10
+ contents: write
11
+ id-token: write
12
+
13
+ environment: release
14
+
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - uses: actions/checkout@v5
19
+ with:
20
+ persist-credentials: false
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ bundler-cache: true
25
+ ruby-version: ruby
26
+ - uses: rubygems/release-gem@v1
data/Gemfile CHANGED
@@ -2,4 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'sqlite3', '~> 1.4'
5
+ gem 'sqlite3'
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Shopify Inc.
1
+ Copyright (c) 2012-today Shopify Inc.
2
2
 
3
3
  MIT License
4
4
 
@@ -6,20 +6,21 @@ require 'ar_transaction_changes/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "ar_transaction_changes"
8
8
  gem.version = ArTransactionChanges::VERSION
9
- gem.authors = ["Dylan Thacker-Smith"]
10
- gem.email = ["Dylan.Smith@shopify.com"]
9
+ gem.authors = ["Dylan Thacker-Smith", "Shopify's Rails Infrastructure Team"]
10
+ gem.email = ["Dylan.Smith@shopify.com", "rails@shopify.com"]
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
- gem.homepage = "https://github.com/dylanahsmith/ar_transaction_changes"
13
+ gem.homepage = "https://github.com/Shopify/ar_transaction_changes"
14
14
  gem.license = "MIT"
15
15
 
16
+ gem.required_ruby_version = ">= 3.2"
17
+
16
18
  gem.files = `git ls-files`.split($/)
17
19
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
20
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
21
  gem.require_paths = ["lib"]
20
22
 
21
- gem.add_dependency "activerecord", ">= 5.2.0"
23
+ gem.add_dependency "activerecord", ">= 7.0.0"
22
24
 
23
25
  gem.add_development_dependency("rake")
24
- gem.add_development_dependency("mysql2")
25
26
  end
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activerecord', github: 'rails/rails', branch: '7-0-stable'
4
+ gem 'sqlite3', '~> 1.4'
5
+
6
+ gemspec path: ".."
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'activerecord', github: 'rails/rails'
3
+ gem 'activerecord', '~> 7.1.0'
4
4
  gem 'sqlite3', '~> 1.4'
5
5
 
6
- gemspec
6
+ gemspec path: ".."
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activerecord', '~> 7.2.0'
4
+ gem 'sqlite3', '~> 1.4'
5
+
6
+ gemspec path: ".."
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activerecord', '~> 8.0.0'
4
+ gem 'sqlite3', '~> 2.1'
5
+
6
+ gemspec path: ".."
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activerecord', github: 'rails/rails', branch: 'main'
4
+ gem 'sqlite3'
5
+
6
+ gemspec path: ".."
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ArTransactionChanges
4
- VERSION = "1.1.8"
4
+ VERSION = "1.1.10"
5
5
  end
@@ -4,16 +4,38 @@ require "ar_transaction_changes/version"
4
4
  require "active_record"
5
5
 
6
6
  module ArTransactionChanges
7
- def _run_commit_callbacks
8
- super
9
- ensure
10
- @transaction_changed_attributes = nil
7
+ def self.included(base)
8
+ if base.respond_to?(:_commit_callbacks) && base.respond_to?(:_rollback_callbacks)
9
+ if !base._commit_callbacks.empty? || !base._rollback_callbacks.empty?
10
+ raise "ArTransactionChanges must be included before defining any after_commit or after_rollback callbacks"
11
+ end
12
+ end
11
13
  end
12
14
 
13
- def _run_rollback_callbacks
14
- super
15
- ensure
16
- @transaction_changed_attributes = nil
15
+ if ActiveRecord.version >= Gem::Version.new('8.1.0.alpha')
16
+ def _run_commit_callbacks!
17
+ super
18
+ ensure
19
+ @transaction_changed_attributes = nil
20
+ end
21
+
22
+ def _run_rollback_callbacks!
23
+ super
24
+ ensure
25
+ @transaction_changed_attributes = nil
26
+ end
27
+ else
28
+ def _run_commit_callbacks
29
+ super
30
+ ensure
31
+ @transaction_changed_attributes = nil
32
+ end
33
+
34
+ def _run_rollback_callbacks
35
+ super
36
+ ensure
37
+ @transaction_changed_attributes = nil
38
+ end
17
39
  end
18
40
 
19
41
  def transaction_changed_attributes
@@ -34,25 +56,37 @@ module ArTransactionChanges
34
56
  end
35
57
  end
36
58
 
59
+ def attribute_will_change!(attr_name)
60
+ unless transaction_changed_attributes.key?(attr_name)
61
+ value = _read_attribute_for_transaction(attr_name)
62
+ value = _deserialize_transaction_change_value(attr_name, value)
63
+ transaction_changed_attributes[attr_name] = value
64
+ end
65
+ super
66
+ end
67
+
37
68
  private
38
69
 
70
+ def init_internals
71
+ super
72
+ @transaction_changed_attributes = nil
73
+ end
74
+
75
+ def _deserialize_transaction_change_value(attr_name, value)
76
+ attribute = @attributes[attr_name]
77
+ return value unless attribute.type.is_a?(::ActiveRecord::Type::Serialized)
78
+ attribute.type.deserialize(value)
79
+ end
80
+
39
81
  def _store_transaction_changed_attributes(attr_name)
40
82
  attr_name = attr_name.to_s
41
83
  old_value = _read_attribute_for_transaction(attr_name)
42
84
  ret = yield
43
85
  new_value = _read_attribute_for_transaction(attr_name)
44
86
  if !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
87
+ transaction_changed_attributes[attr_name] = _deserialize_transaction_change_value(attr_name, old_value)
51
88
  elsif transaction_changed_attributes.key?(attr_name)
52
- attribute = @attributes[attr_name]
53
- if attribute.type.is_a?(::ActiveRecord::Type::Serialized)
54
- new_value = attribute.type.deserialize(new_value)
55
- end
89
+ new_value = _deserialize_transaction_change_value(attr_name, new_value)
56
90
 
57
91
  stored_value = transaction_changed_attributes[attr_name]
58
92
 
data/test/models/user.rb CHANGED
@@ -9,8 +9,13 @@ class User < ActiveRecord::Base
9
9
  end
10
10
  end
11
11
 
12
- serialize :connection_details, Array
13
- serialize :notes, Array
12
+ if ActiveRecord.gem_version >= Gem::Version.new('7.1.0')
13
+ serialize :connection_details, type: Array
14
+ serialize :notes, type: Array
15
+ else
16
+ serialize :connection_details, Array
17
+ serialize :notes, Array
18
+ end
14
19
 
15
20
  attr_accessor :stored_transaction_changes
16
21
 
data/test/test_helper.rb CHANGED
@@ -28,3 +28,10 @@ ActiveRecord::Base.connection.tap do |db|
28
28
  end
29
29
 
30
30
  Dir[test_dir.join("models/*.rb")].each{ |file| require file }
31
+
32
+ serializable_classes = [User::ConnectionDetails]
33
+ if ActiveRecord::VERSION::MAJOR >= 7
34
+ ActiveRecord.yaml_column_permitted_classes += serializable_classes
35
+ else
36
+ ActiveRecord::Base.yaml_column_permitted_classes += serializable_classes
37
+ end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class TransactionChangesTest < MiniTest::Unit::TestCase
3
+ class TransactionChangesTest < Minitest::Test
4
4
  def setup
5
5
  @user = User.new(:name => "Dylan", :occupation => "Developer", age: 20)
6
6
  @user.save!
@@ -153,4 +153,49 @@ class TransactionChangesTest < MiniTest::Unit::TestCase
153
153
 
154
154
  assert_empty @user.stored_transaction_changes
155
155
  end
156
+
157
+ def test_mutating_serialized_attribute_in_place_with_attribute_will_change
158
+ @user.notes_will_change!
159
+ @user.notes.push('a')
160
+ @user.save!
161
+
162
+ assert_equal [[], ['a']], @user.stored_transaction_changes['notes']
163
+ end
164
+
165
+ def test_double_modification_with_attribute_will_change
166
+ @user.transaction do
167
+ @user.notes = ['a']
168
+ @user.save!
169
+
170
+ @user.notes_will_change!
171
+ @user.notes.push('b')
172
+ @user.save!
173
+ end
174
+
175
+ assert_equal [[], ['a', 'b']], @user.stored_transaction_changes['notes']
176
+ end
177
+
178
+ def test_do_not_allow_adding_this_gem_to_a_model_after_commit_callbacks_are_defined
179
+ assert_raises(RuntimeError) do
180
+ Class.new(ActiveRecord::Base) do
181
+ after_commit :some_method
182
+
183
+ include ArTransactionChanges
184
+
185
+ def some_method; end
186
+ end
187
+ end
188
+ end
189
+
190
+ def test_do_not_allow_adding_this_gem_to_a_model_after_rollback_callbacks_are_defined
191
+ assert_raises(RuntimeError) do
192
+ Class.new(ActiveRecord::Base) do
193
+ after_rollback :some_method
194
+
195
+ include ArTransactionChanges
196
+
197
+ def some_method; end
198
+ end
199
+ end
200
+ end
156
201
  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.8
4
+ version: 1.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Thacker-Smith
8
- autorequire:
8
+ - Shopify's Rails Infrastructure Team
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-04 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.2.0
19
+ version: 7.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.2.0
26
+ version: 7.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,48 +38,39 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: mysql2
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  description: Solves the problem of trying to get all the changes to an object during
56
42
  a transaction in an after_commit callbacks.
57
43
  email:
58
44
  - Dylan.Smith@shopify.com
45
+ - rails@shopify.com
59
46
  executables: []
60
47
  extensions: []
61
48
  extra_rdoc_files: []
62
49
  files:
50
+ - ".devcontainer/devcontainer.json"
63
51
  - ".github/workflows/ci.yml"
52
+ - ".github/workflows/release.yml"
64
53
  - ".gitignore"
65
54
  - Gemfile
66
- - Gemfile.rails52
67
- - Gemfile.rails_head
68
55
  - LICENSE.txt
69
56
  - README.md
70
57
  - Rakefile
71
58
  - ar_transaction_changes.gemspec
59
+ - gemfiles/rails_7.0.gemfile
60
+ - gemfiles/rails_7.1.gemfile
61
+ - gemfiles/rails_7.2.gemfile
62
+ - gemfiles/rails_8.0.gemfile
63
+ - gemfiles/rails_head.gemfile
72
64
  - lib/ar_transaction_changes.rb
73
65
  - lib/ar_transaction_changes/version.rb
74
66
  - test/database.yml.default
75
67
  - test/models/user.rb
76
68
  - test/test_helper.rb
77
69
  - test/transaction_changes_test.rb
78
- homepage: https://github.com/dylanahsmith/ar_transaction_changes
70
+ homepage: https://github.com/Shopify/ar_transaction_changes
79
71
  licenses:
80
72
  - MIT
81
73
  metadata: {}
82
- post_install_message:
83
74
  rdoc_options: []
84
75
  require_paths:
85
76
  - lib
@@ -87,15 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
78
  requirements:
88
79
  - - ">="
89
80
  - !ruby/object:Gem::Version
90
- version: '0'
81
+ version: '3.2'
91
82
  required_rubygems_version: !ruby/object:Gem::Requirement
92
83
  requirements:
93
84
  - - ">="
94
85
  - !ruby/object:Gem::Version
95
86
  version: '0'
96
87
  requirements: []
97
- rubygems_version: 3.1.4
98
- signing_key:
88
+ rubygems_version: 3.6.9
99
89
  specification_version: 4
100
90
  summary: Store transaction changes for active record objects
101
91
  test_files:
data/Gemfile.rails52 DELETED
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem 'activerecord', '~> 5.2.0'
4
- gem "sqlite3", "~> 1.3", ">= 1.3.6"
5
-
6
- gemspec