activerecord-spanner-adapter 1.5.0 → 1.6.0

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/acceptance-tests-on-emulator.yaml +1 -1
  3. data/.github/workflows/acceptance-tests-on-production.yaml +5 -3
  4. data/.github/workflows/ci.yaml +1 -1
  5. data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +1 -1
  6. data/.github/workflows/nightly-acceptance-tests-on-production.yaml +5 -3
  7. data/.github/workflows/nightly-unit-tests.yaml +1 -1
  8. data/.github/workflows/release-please-label.yml +1 -1
  9. data/.release-please-manifest.json +1 -1
  10. data/CHANGELOG.md +14 -0
  11. data/Gemfile +5 -2
  12. data/README.md +10 -10
  13. data/acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb +6 -0
  14. data/acceptance/cases/migration/change_schema_test.rb +19 -3
  15. data/acceptance/cases/migration/schema_dumper_test.rb +10 -1
  16. data/acceptance/cases/models/insert_all_test.rb +22 -0
  17. data/acceptance/cases/models/interleave_test.rb +6 -0
  18. data/acceptance/cases/tasks/database_tasks_test.rb +340 -2
  19. data/acceptance/cases/transactions/optimistic_locking_test.rb +6 -0
  20. data/acceptance/cases/transactions/read_write_transactions_test.rb +24 -0
  21. data/acceptance/models/table_with_sequence.rb +10 -0
  22. data/acceptance/schema/schema.rb +65 -19
  23. data/acceptance/test_helper.rb +1 -1
  24. data/activerecord-spanner-adapter.gemspec +1 -1
  25. data/examples/snippets/bit-reversed-sequence/README.md +103 -0
  26. data/examples/snippets/bit-reversed-sequence/Rakefile +13 -0
  27. data/examples/snippets/bit-reversed-sequence/application.rb +68 -0
  28. data/examples/snippets/bit-reversed-sequence/config/database.yml +8 -0
  29. data/examples/snippets/bit-reversed-sequence/db/migrate/01_create_tables.rb +33 -0
  30. data/examples/snippets/bit-reversed-sequence/db/schema.rb +31 -0
  31. data/examples/snippets/bit-reversed-sequence/db/seeds.rb +31 -0
  32. data/examples/snippets/bit-reversed-sequence/models/album.rb +11 -0
  33. data/examples/snippets/bit-reversed-sequence/models/singer.rb +15 -0
  34. data/examples/snippets/interleaved-tables/README.md +44 -53
  35. data/examples/snippets/interleaved-tables/Rakefile +2 -2
  36. data/examples/snippets/interleaved-tables/application.rb +2 -2
  37. data/examples/snippets/interleaved-tables/db/migrate/01_create_tables.rb +12 -18
  38. data/examples/snippets/interleaved-tables/db/schema.rb +9 -7
  39. data/examples/snippets/interleaved-tables/db/seeds.rb +1 -1
  40. data/examples/snippets/interleaved-tables/models/album.rb +3 -7
  41. data/examples/snippets/interleaved-tables/models/singer.rb +1 -1
  42. data/examples/snippets/interleaved-tables/models/track.rb +6 -7
  43. data/examples/snippets/interleaved-tables-before-7.1/README.md +167 -0
  44. data/examples/snippets/interleaved-tables-before-7.1/Rakefile +13 -0
  45. data/examples/snippets/interleaved-tables-before-7.1/application.rb +126 -0
  46. data/examples/snippets/interleaved-tables-before-7.1/config/database.yml +8 -0
  47. data/examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb +44 -0
  48. data/examples/snippets/interleaved-tables-before-7.1/db/schema.rb +37 -0
  49. data/examples/snippets/interleaved-tables-before-7.1/db/seeds.rb +40 -0
  50. data/examples/snippets/interleaved-tables-before-7.1/models/album.rb +20 -0
  51. data/examples/snippets/interleaved-tables-before-7.1/models/singer.rb +18 -0
  52. data/examples/snippets/interleaved-tables-before-7.1/models/track.rb +28 -0
  53. data/examples/snippets/query-logs/README.md +43 -0
  54. data/examples/snippets/query-logs/Rakefile +13 -0
  55. data/examples/snippets/query-logs/application.rb +63 -0
  56. data/examples/snippets/query-logs/config/database.yml +8 -0
  57. data/examples/snippets/query-logs/db/migrate/01_create_tables.rb +21 -0
  58. data/examples/snippets/query-logs/db/schema.rb +31 -0
  59. data/examples/snippets/query-logs/db/seeds.rb +24 -0
  60. data/examples/snippets/query-logs/models/album.rb +9 -0
  61. data/examples/snippets/query-logs/models/singer.rb +9 -0
  62. data/lib/active_record/connection_adapters/spanner/column.rb +13 -0
  63. data/lib/active_record/connection_adapters/spanner/database_statements.rb +144 -35
  64. data/lib/active_record/connection_adapters/spanner/schema_cache.rb +3 -21
  65. data/lib/active_record/connection_adapters/spanner/schema_creation.rb +11 -0
  66. data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +4 -0
  67. data/lib/active_record/connection_adapters/spanner/schema_statements.rb +3 -2
  68. data/lib/active_record/connection_adapters/spanner_adapter.rb +28 -9
  69. data/lib/activerecord_spanner_adapter/base.rb +58 -21
  70. data/lib/activerecord_spanner_adapter/information_schema.rb +33 -24
  71. data/lib/activerecord_spanner_adapter/primary_key.rb +1 -1
  72. data/lib/activerecord_spanner_adapter/table/column.rb +4 -9
  73. data/lib/activerecord_spanner_adapter/version.rb +1 -1
  74. data/lib/arel/visitors/spanner.rb +3 -1
  75. metadata +33 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b10ee1d169ad72da934b5d726114d5b9ac215103c54b607a0fe0c18b2ed4876
4
- data.tar.gz: 3a2e65fd406507987da6a38cbcc38130da9a3200e7ad1f2b5909701916903ab8
3
+ metadata.gz: 2ad2384bb1890bb224c89a146c42f615f89c6e2892848da5e701a091d90fa95b
4
+ data.tar.gz: 0e8a9c608068ff30011bc9bca68b10ab0d22b910260a37a6d4a492365adf78b0
5
5
  SHA512:
6
- metadata.gz: 1a842880cf43a9316cb76dba5a9ef0ecf576db7102a1d03a9ecd14308232801bb296701e6b8d1506a78d7895b61eec14f7e9b887e1d44dc075ba576076c2a6c5
7
- data.tar.gz: c2c9af94b3d25a19098edfe18c2bb479826ec6996e76ec0c8a3e50280988a0aee694decb8df6452d1a1bb2bee6be1e8338ace5f4bf588d96fa6781de44c13f74
6
+ metadata.gz: 1894765bbc1e3dfac270d73199a4f235ae95724ca18145d6850cce27c38ef2018b59e9035cf2fa91bc30d3f650e080b8eea58c3e91a66035db3a4d07c35ca1be
7
+ data.tar.gz: 4a9b93d7990fa78f901864bed816e75ff5d0f9da34a530c7107f475d8fd06dc71817fbf8b2c1e0262e4656bf7ab363917ecf7b7c82315b6d5fa84cce0d22489d
@@ -19,7 +19,7 @@ jobs:
19
19
  max-parallel: 4
20
20
  matrix:
21
21
  ruby: ["2.7", "3.0", "3.1", "3.2"]
22
- ar: ["~> 6.0.6", "~> 6.1.7", "~> 7.0.4"]
22
+ ar: ["~> 6.0.6", "~> 6.1.7", "~> 7.0.4", "~> 7.1.0"]
23
23
  # Exclude combinations that are not supported.
24
24
  exclude:
25
25
  - ruby: "3.0"
@@ -34,12 +34,14 @@ jobs:
34
34
  with:
35
35
  bundler-cache: true
36
36
  ruby-version: ${{ matrix.ruby }}
37
+ - name: Authenticate Google Cloud
38
+ uses: google-github-actions/auth@v2
39
+ with:
40
+ credentials_json: ${{ secrets.GCP_SA_KEY }}
37
41
  - name: Setup GCloud
38
- uses: google-github-actions/setup-gcloud@v0
42
+ uses: google-github-actions/setup-gcloud@v2
39
43
  with:
40
44
  project_id: ${{ secrets.GCP_PROJECT_ID }}
41
- service_account_key: ${{ secrets.GCP_SA_KEY }}
42
- export_default_credentials: true
43
45
  - name: Install dependencies
44
46
  run: bundle install
45
47
  - name: Run acceptance tests on production
@@ -11,7 +11,7 @@ jobs:
11
11
  max-parallel: 4
12
12
  matrix:
13
13
  ruby: ["2.7", "3.0", "3.1", "3.2"]
14
- ar: ["~> 6.0.6", "~> 6.1.7", "~> 7.0.4"]
14
+ ar: ["~> 6.0.6", "~> 6.1.7", "~> 7.0.4", "~> 7.1.0"]
15
15
  # Exclude combinations that are not supported.
16
16
  exclude:
17
17
  - ruby: "3.0"
@@ -20,7 +20,7 @@ jobs:
20
20
  matrix:
21
21
  # Run acceptance tests all supported combinations of Ruby and ActiveRecord.
22
22
  ruby: [2.7, 3.0, 3.1, 3.2]
23
- ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5, 7.0.6, 7.0.7]
23
+ ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5, 7.0.6, 7.0.7, 7.1.0, 7.1.1, 7.1.2]
24
24
  # Exclude combinations that are not supported.
25
25
  exclude:
26
26
  - ruby: 3.0
@@ -20,12 +20,14 @@ jobs:
20
20
  with:
21
21
  bundler-cache: true
22
22
  ruby-version: ${{ matrix.ruby }}
23
+ - name: Authenticate Google Cloud
24
+ uses: google-github-actions/auth@v2
25
+ with:
26
+ credentials_json: ${{ secrets.GCP_SA_KEY }}
23
27
  - name: Setup GCloud
24
- uses: google-github-actions/setup-gcloud@v0
28
+ uses: google-github-actions/setup-gcloud@v2
25
29
  with:
26
30
  project_id: ${{ secrets.GCP_PROJECT_ID }}
27
- service_account_key: ${{ secrets.GCP_SA_KEY }}
28
- export_default_credentials: true
29
31
  - name: Install dependencies
30
32
  run: bundle install
31
33
  - name: Run acceptance tests on production
@@ -12,7 +12,7 @@ jobs:
12
12
  matrix:
13
13
  # Run unit tests all supported combinations of Ruby and ActiveRecord.
14
14
  ruby: [2.7, 3.0, 3.1, 3.2]
15
- ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5]
15
+ ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5, 7.1.0, 7.1.1, 7.1.2]
16
16
  # Exclude combinations that are not supported.
17
17
  exclude:
18
18
  - ruby: 3.0
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - name: ReleaseLabel
14
- uses: actions/github-script@v6
14
+ uses: actions/github-script@v7
15
15
  with:
16
16
  github-token: ${{secrets.YOSHI_APPROVER_TOKEN}}
17
17
  script: |
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.5.0"
2
+ ".": "1.6.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ### 1.6.0 (2023-12-20)
4
+
5
+ #### Features
6
+
7
+ * interleaved tables with built-in composite pk ([#282](https://github.com/googleapis/ruby-spanner-activerecord/issues/282))
8
+ * support Query Logs ([#291](https://github.com/googleapis/ruby-spanner-activerecord/issues/291))
9
+ * support Rails 7.1 ([#278](https://github.com/googleapis/ruby-spanner-activerecord/issues/278))
10
+
11
+ ### 1.5.1 (2023-12-12)
12
+
13
+ #### Bug Fixes
14
+
15
+ * more permissive arg passthrough for insert_all and upsert_all ([#283](https://github.com/googleapis/ruby-spanner-activerecord/issues/283))
16
+
3
17
  ### 1.5.0 (2023-11-03)
4
18
 
5
19
  #### Features
data/Gemfile CHANGED
@@ -4,12 +4,15 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "activerecord", ENV.fetch("AR_VERSION", "~> 6.1.6.1")
7
- gem "minitest", "~> 5.19.0"
7
+ gem "minitest", "~> 5.20.0"
8
+ gem "minitest-rg", "~> 5.3.0"
8
9
  gem "pry", "~> 0.13.0"
9
10
  gem "pry-byebug", "~> 3.9.0"
10
11
 
11
12
  # Required for samples and testing.
12
- gem "composite_primary_keys"
13
+ install_if -> { ENV.fetch("AR_VERSION", "~> 6.1.6.1").dup.to_s.sub!("~>", "").strip < "7.1.0" && !ENV["SKIP_COMPOSITE_PK"] } do
14
+ gem "composite_primary_keys"
15
+ end
13
16
 
14
17
  # Required for samples
15
18
  gem "docker-api"
data/README.md CHANGED
@@ -84,19 +84,19 @@ Some noteworthy examples in the snippets directory:
84
84
  for inserting, updating and deleting data in a Cloud Spanner database. Mutations can have a significant performance
85
85
  advantage compared to DML statements, but do not allow read-your-writes semantics during a transaction.
86
86
  - [array-data-type](examples/snippets/array-data-type): Shows how to work with `ARRAY` data types.
87
- - [interleaved-tables](examples/snippets/interleaved-tables): Shows how to work with [Interleaved Tables](https://cloud.google.com/spanner/docs/schema-and-data-model#create-interleaved-tables).
87
+ - [interleaved-tables](examples/snippets/interleaved-tables-before-7.1): Shows how to work with [Interleaved Tables](https://cloud.google.com/spanner/docs/schema-and-data-model#create-interleaved-tables).
88
88
 
89
89
  ## Limitations
90
90
 
91
- Limitation|Comment|Resolution
92
- ---|---|---
93
- Interleaved tables require composite primary keys| Cloud Spanner requires composite primary keys for interleaved tables. See {file:examples/snippets/interleaved-tables/README.md this example} for an example on how to use interleaved tables with ActiveRecord |Use composite primary keys.
94
- Lack of sequential and auto-assigned IDs|Cloud Spanner doesn't autogenerate IDs and this integration instead creates UUID4 to avoid [hotspotting](https://cloud.google.com/spanner/docs/schema-design#uuid_primary_key) so you SHOULD NOT rely on IDs being sorted| UUID4s are automatically generated for primary keys.
95
- Table without Primary Key| Cloud Spanner support does not support tables without a primary key.| Always define a primary key for your table.
96
- Table names CANNOT have spaces within them whether back-ticked or not|Cloud Spanner DOES NOT support tables with spaces in them for example `Entity ID`|Ensure that your table names don't contain spaces.
97
- Table names CANNOT have punctuation marks and MUST contain valid UTF-8|Cloud Spanner DOES NOT support punctuation marks e.g. periods ".", question marks "?" in table names|Ensure that your table names don't contain punctuation marks.
98
- Index with fields length [add_index](https://apidock.com/rails/v5.2.3/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index)|Cloud Spanner does not support index with fields length | Ensure that your database definition does not include index definitions with field lengths.
99
- Only GoogleSQL-dialect databases| Cloud Spanner supports both GoogleSQL- and PostgreSQL-dialect databases. This adapter only supports GoogleSQL-dialect databases. | Ensure that your database uses the GoogleSQL dialect.
91
+ | Limitation | Comment | Resolution |
92
+ |-----------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
93
+ | Interleaved tables require composite primary keys | Cloud Spanner requires composite primary keys for interleaved tables. See {file:examples/snippets/interleaved-tables/README.md this example} for an example on how to use interleaved tables with ActiveRecord | Use composite primary keys. |
94
+ | Lack of sequential IDs | Cloud Spanner uses either using bit-reversed sequences or UUID4 to generated primary keys to avoid [hotspotting](https://cloud.google.com/spanner/docs/schema-design#uuid_primary_key) so you SHOULD NOT rely on IDs being sorted | Use either UUID4s or bit-reversed sequences to automatically generate primary keys. |
95
+ | Table without Primary Key | Cloud Spanner support does not support tables without a primary key. | Always define a primary key for your table. |
96
+ | Table names CANNOT have spaces within them whether back-ticked or not | Cloud Spanner DOES NOT support tables with spaces in them for example `Entity ID` | Ensure that your table names don't contain spaces. |
97
+ | Table names CANNOT have punctuation marks and MUST contain valid UTF-8 | Cloud Spanner DOES NOT support punctuation marks e.g. periods ".", question marks "?" in table names | Ensure that your table names don't contain punctuation marks. |
98
+ | Index with fields length [add_index](https://apidock.com/rails/v5.2.3/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index) | Cloud Spanner does not support index with fields length | Ensure that your database definition does not include index definitions with field lengths. |
99
+ | Only GoogleSQL-dialect databases | Cloud Spanner supports both GoogleSQL- and PostgreSQL-dialect databases. This adapter only supports GoogleSQL-dialect databases. | Ensure that your database uses the GoogleSQL dialect. |
100
100
 
101
101
  ## Contributing
102
102
 
@@ -6,6 +6,12 @@
6
6
 
7
7
  # frozen_string_literal: true
8
8
 
9
+ # ActiveRecord 7.1 introduced native support for composite primary keys.
10
+ # This deprecates the https://github.com/composite-primary-keys/composite_primary_keys gem that was previously used in
11
+ # this library to support composite primary keys, which again are needed for interleaved tables. These tests use the
12
+ # third-party composite primary key gem and are therefore not executed for Rails 7.1 and higher.
13
+ return if ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
14
+
9
15
  require "test_helper"
10
16
  require "models/singer"
11
17
  require "models/album"
@@ -196,8 +196,14 @@ module ActiveRecord
196
196
  end
197
197
  end
198
198
  end
199
+ expected = if ActiveRecord::gem_version < Gem::Version.create('7.1.0')
200
+ "you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table."
201
+ else
202
+ "you can't redefine the primary key column 'id' on 'testings'. To define a custom primary key, pass { id: false } to create_table."
203
+ end
204
+
199
205
 
200
- assert_equal "you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table.", error.message
206
+ assert_equal expected, error.message
201
207
  end
202
208
 
203
209
  def test_create_table_raises_when_redefining_custom_primary_key_column
@@ -209,7 +215,12 @@ module ActiveRecord
209
215
  end
210
216
  end
211
217
 
212
- assert_equal "you can't redefine the primary key column 'testing_id'. To define a custom primary key, pass { id: false } to create_table.", error.message
218
+ expected = if ActiveRecord::gem_version < Gem::Version.create('7.1.0')
219
+ "you can't redefine the primary key column 'testing_id'. To define a custom primary key, pass { id: false } to create_table."
220
+ else
221
+ "you can't redefine the primary key column 'testing_id' on 'testings'. To define a custom primary key, pass { id: false } to create_table."
222
+ end
223
+ assert_equal expected, error.message
213
224
  end
214
225
 
215
226
  def test_create_table_raises_when_defining_existing_column
@@ -222,7 +233,12 @@ module ActiveRecord
222
233
  end
223
234
  end
224
235
 
225
- assert_equal "you can't define an already defined column 'testing_column'.", error.message
236
+ expected = if ActiveRecord::gem_version < Gem::Version.create('7.1.0')
237
+ "you can't define an already defined column 'testing_column'."
238
+ else
239
+ "you can't define an already defined column 'testing_column' on 'testings'."
240
+ end
241
+ assert_equal expected, error.message
226
242
  end
227
243
 
228
244
  def test_create_table_with_timestamps_should_create_datetime_columns
@@ -13,6 +13,10 @@ module ActiveRecord
13
13
  class IndexTest < SpannerAdapter::TestCase
14
14
  include SpannerAdapter::Migration::TestHelper
15
15
 
16
+ def is_7_1_or_higher?
17
+ ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
18
+ end
19
+
16
20
  def test_dump_schema_contains_start_batch_ddl
17
21
  connection = ActiveRecord::Base.connection
18
22
  schema = StringIO.new
@@ -34,7 +38,12 @@ module ActiveRecord
34
38
  connection = ActiveRecord::Base.connection
35
39
  schema = StringIO.new
36
40
  ActiveRecord::SchemaDumper.dump connection, schema
37
- assert schema.string.include?("create_table \"albums\", primary_key: \"albumid\"")
41
+ sql = schema.string
42
+ if is_7_1_or_higher?
43
+ assert schema.string.include?("create_table \"albums\", primary_key: [\"singerid\", \"albumid\"]"), sql
44
+ else
45
+ assert schema.string.include?("create_table \"albums\", primary_key: \"albumid\""), sql
46
+ end
38
47
  end
39
48
 
40
49
  def test_dump_schema_contains_interleaved_index
@@ -33,6 +33,12 @@ module ActiveRecord
33
33
  assert_raise(NotImplementedError) { Author.insert_all(values) }
34
34
  end
35
35
 
36
+ def test_insert
37
+ value = { id: Author.next_sequence_value, name: "Alice" }
38
+
39
+ assert_raise(NotImplementedError) { Author.insert(value) }
40
+ end
41
+
36
42
  def test_insert_all!
37
43
  values = [
38
44
  { id: Author.next_sequence_value, name: "Alice" },
@@ -85,6 +91,22 @@ module ActiveRecord
85
91
  assert_equal "Carol", authors[2].name
86
92
  end
87
93
 
94
+ def test_upsert
95
+ Author.create id: 1, name: "David"
96
+ authors = Author.all.order(:name)
97
+ assert_equal 1, authors.length
98
+ assert_equal "David", authors[0].name
99
+
100
+ value = { id: 1, name: "Alice" }
101
+
102
+ Author.upsert(value)
103
+
104
+ authors = Author.all.order(:name)
105
+
106
+ assert_equal 1, authors.length
107
+ assert_equal "Alice", authors[0].name
108
+ end
109
+
88
110
  def test_upsert_all
89
111
  Author.create id: 1, name: "David"
90
112
  authors = Author.all.order(:name)
@@ -6,6 +6,12 @@
6
6
 
7
7
  # frozen_string_literal: true
8
8
 
9
+ # ActiveRecord 7.1 introduced native support for composite primary keys.
10
+ # This deprecates the https://github.com/composite-primary-keys/composite_primary_keys gem that was previously used in
11
+ # this library to support composite primary keys, which again are needed for interleaved tables. These tests use the
12
+ # third-party composite primary key gem and are therefore not executed for Rails 7.1 and higher.
13
+ return if ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
14
+
9
15
  require "test_helper"
10
16
  require "test_helpers/with_separate_database"
11
17