activerecord-import 1.0.2 → 1.7.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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +151 -0
  3. data/.gitignore +5 -0
  4. data/.rubocop.yml +74 -8
  5. data/.rubocop_todo.yml +10 -16
  6. data/Brewfile +3 -1
  7. data/CHANGELOG.md +138 -3
  8. data/Dockerfile +23 -0
  9. data/Gemfile +24 -14
  10. data/LICENSE +21 -56
  11. data/README.markdown +108 -60
  12. data/Rakefile +3 -0
  13. data/activerecord-import.gemspec +6 -5
  14. data/benchmarks/benchmark.rb +10 -4
  15. data/benchmarks/lib/base.rb +4 -2
  16. data/benchmarks/lib/cli_parser.rb +4 -2
  17. data/benchmarks/lib/float.rb +2 -0
  18. data/benchmarks/lib/mysql2_benchmark.rb +2 -0
  19. data/benchmarks/lib/output_to_csv.rb +2 -0
  20. data/benchmarks/lib/output_to_html.rb +4 -2
  21. data/benchmarks/models/test_innodb.rb +2 -0
  22. data/benchmarks/models/test_memory.rb +2 -0
  23. data/benchmarks/models/test_myisam.rb +2 -0
  24. data/benchmarks/schema/{mysql_schema.rb → mysql2_schema.rb} +2 -0
  25. data/docker-compose.yml +34 -0
  26. data/gemfiles/4.2.gemfile +2 -0
  27. data/gemfiles/5.0.gemfile +2 -0
  28. data/gemfiles/5.1.gemfile +2 -0
  29. data/gemfiles/5.2.gemfile +2 -0
  30. data/gemfiles/6.0.gemfile +4 -1
  31. data/gemfiles/6.1.gemfile +4 -1
  32. data/gemfiles/7.0.gemfile +4 -0
  33. data/gemfiles/7.1.gemfile +3 -0
  34. data/lib/activerecord-import/active_record/adapters/abstract_adapter.rb +2 -0
  35. data/lib/activerecord-import/active_record/adapters/jdbcmysql_adapter.rb +6 -4
  36. data/lib/activerecord-import/active_record/adapters/jdbcpostgresql_adapter.rb +2 -0
  37. data/lib/activerecord-import/active_record/adapters/jdbcsqlite3_adapter.rb +2 -0
  38. data/lib/activerecord-import/active_record/adapters/mysql2_adapter.rb +2 -0
  39. data/lib/activerecord-import/active_record/adapters/postgresql_adapter.rb +2 -0
  40. data/lib/activerecord-import/active_record/adapters/seamless_database_pool_adapter.rb +2 -0
  41. data/lib/activerecord-import/active_record/adapters/sqlite3_adapter.rb +2 -0
  42. data/lib/activerecord-import/active_record/adapters/trilogy_adapter.rb +8 -0
  43. data/lib/activerecord-import/adapters/abstract_adapter.rb +14 -5
  44. data/lib/activerecord-import/adapters/em_mysql2_adapter.rb +2 -0
  45. data/lib/activerecord-import/adapters/mysql2_adapter.rb +2 -0
  46. data/lib/activerecord-import/adapters/mysql_adapter.rb +33 -25
  47. data/lib/activerecord-import/adapters/postgresql_adapter.rb +69 -56
  48. data/lib/activerecord-import/adapters/sqlite3_adapter.rb +39 -39
  49. data/lib/activerecord-import/adapters/trilogy_adapter.rb +7 -0
  50. data/lib/activerecord-import/base.rb +10 -2
  51. data/lib/activerecord-import/import.rb +162 -65
  52. data/lib/activerecord-import/mysql2.rb +2 -0
  53. data/lib/activerecord-import/postgresql.rb +2 -0
  54. data/lib/activerecord-import/sqlite3.rb +2 -0
  55. data/lib/activerecord-import/synchronize.rb +3 -1
  56. data/lib/activerecord-import/value_sets_parser.rb +5 -0
  57. data/lib/activerecord-import/version.rb +3 -1
  58. data/lib/activerecord-import.rb +2 -1
  59. data/test/adapters/jdbcmysql.rb +2 -0
  60. data/test/adapters/jdbcpostgresql.rb +2 -0
  61. data/test/adapters/jdbcsqlite3.rb +2 -0
  62. data/test/adapters/makara_postgis.rb +2 -0
  63. data/test/adapters/mysql2.rb +2 -0
  64. data/test/adapters/mysql2_makara.rb +2 -0
  65. data/test/adapters/mysql2spatial.rb +2 -0
  66. data/test/adapters/postgis.rb +2 -0
  67. data/test/adapters/postgresql.rb +2 -0
  68. data/test/adapters/postgresql_makara.rb +2 -0
  69. data/test/adapters/seamless_database_pool.rb +2 -0
  70. data/test/adapters/spatialite.rb +2 -0
  71. data/test/adapters/sqlite3.rb +2 -0
  72. data/test/adapters/trilogy.rb +9 -0
  73. data/test/database.yml.sample +7 -0
  74. data/test/{travis → github}/database.yml +7 -1
  75. data/test/import_test.rb +93 -2
  76. data/test/jdbcmysql/import_test.rb +5 -3
  77. data/test/jdbcpostgresql/import_test.rb +4 -2
  78. data/test/jdbcsqlite3/import_test.rb +4 -2
  79. data/test/makara_postgis/import_test.rb +4 -2
  80. data/test/models/account.rb +2 -0
  81. data/test/models/alarm.rb +2 -0
  82. data/test/models/animal.rb +8 -0
  83. data/test/models/author.rb +7 -0
  84. data/test/models/bike_maker.rb +3 -0
  85. data/test/models/book.rb +7 -2
  86. data/test/models/car.rb +2 -0
  87. data/test/models/card.rb +5 -0
  88. data/test/models/chapter.rb +2 -0
  89. data/test/models/composite_book.rb +19 -0
  90. data/test/models/composite_chapter.rb +9 -0
  91. data/test/models/customer.rb +18 -0
  92. data/test/models/deck.rb +8 -0
  93. data/test/models/dictionary.rb +2 -0
  94. data/test/models/discount.rb +2 -0
  95. data/test/models/end_note.rb +2 -0
  96. data/test/models/group.rb +2 -0
  97. data/test/models/order.rb +17 -0
  98. data/test/models/playing_card.rb +4 -0
  99. data/test/models/promotion.rb +2 -0
  100. data/test/models/question.rb +2 -0
  101. data/test/models/rule.rb +2 -0
  102. data/test/models/tag.rb +9 -1
  103. data/test/models/tag_alias.rb +11 -0
  104. data/test/models/topic.rb +7 -0
  105. data/test/models/user.rb +2 -0
  106. data/test/models/user_token.rb +2 -0
  107. data/test/models/vendor.rb +2 -0
  108. data/test/models/widget.rb +2 -0
  109. data/test/mysql2/import_test.rb +5 -3
  110. data/test/mysql2_makara/import_test.rb +5 -3
  111. data/test/mysqlspatial2/import_test.rb +5 -3
  112. data/test/postgis/import_test.rb +4 -2
  113. data/test/postgresql/import_test.rb +4 -2
  114. data/test/schema/generic_schema.rb +37 -1
  115. data/test/schema/jdbcpostgresql_schema.rb +3 -1
  116. data/test/schema/mysql2_schema.rb +2 -0
  117. data/test/schema/postgis_schema.rb +3 -1
  118. data/test/schema/postgresql_schema.rb +47 -0
  119. data/test/schema/sqlite3_schema.rb +2 -0
  120. data/test/schema/version.rb +2 -0
  121. data/test/sqlite3/import_test.rb +4 -2
  122. data/test/support/active_support/test_case_extensions.rb +2 -0
  123. data/test/support/assertions.rb +2 -0
  124. data/test/support/factories.rb +2 -0
  125. data/test/support/generate.rb +4 -2
  126. data/test/support/mysql/import_examples.rb +2 -1
  127. data/test/support/postgresql/import_examples.rb +108 -2
  128. data/test/support/shared_examples/on_duplicate_key_ignore.rb +2 -0
  129. data/test/support/shared_examples/on_duplicate_key_update.rb +78 -9
  130. data/test/support/shared_examples/recursive_import.rb +98 -1
  131. data/test/support/sqlite3/import_examples.rb +2 -1
  132. data/test/synchronize_test.rb +2 -0
  133. data/test/test_helper.rb +33 -6
  134. data/test/trilogy/import_test.rb +7 -0
  135. data/test/value_sets_bytes_parser_test.rb +3 -1
  136. data/test/value_sets_records_parser_test.rb +3 -1
  137. metadata +42 -16
  138. data/.travis.yml +0 -70
  139. data/gemfiles/3.2.gemfile +0 -2
  140. data/gemfiles/4.0.gemfile +0 -2
  141. data/gemfiles/4.1.gemfile +0 -2
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  warn <<-MSG
2
4
  [DEPRECATION] loading activerecord-import via 'require "activerecord-import/<adapter-name>"'
3
5
  is deprecated. Update to autorequire using 'require "activerecord-import"'. See
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  warn <<-MSG
2
4
  [DEPRECATION] loading activerecord-import via 'require "activerecord-import/<adapter-name>"'
3
5
  is deprecated. Update to autorequire using 'require "activerecord-import"'. See
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord # :nodoc:
2
4
  class Base # :nodoc:
3
5
  # Synchronizes the passed in ActiveRecord instances with data
@@ -39,7 +41,7 @@ module ActiveRecord # :nodoc:
39
41
 
40
42
  next unless matched_instance
41
43
 
42
- instance.send :clear_association_cache
44
+ instance.instance_variable_set :@association_cache, {}
43
45
  instance.send :clear_aggregation_cache if instance.respond_to?(:clear_aggregation_cache, true)
44
46
  instance.instance_variable_set :@attributes, matched_instance.instance_variable_get(:@attributes)
45
47
 
@@ -1,6 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/array'
4
+
1
5
  module ActiveRecord::Import
2
6
  class ValueSetTooLargeError < StandardError
3
7
  attr_reader :size
8
+
4
9
  def initialize(msg = "Value set exceeds max size", size = 0)
5
10
  @size = size
6
11
  super(msg)
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Import
3
- VERSION = "1.0.2".freeze
5
+ VERSION = "1.7.0"
4
6
  end
5
7
  end
@@ -1,4 +1,5 @@
1
- # rubocop:disable Style/FileName
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/lazy_load_hooks"
3
4
 
4
5
  ActiveSupport.on_load(:active_record) do
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "jdbcmysql"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "jdbcpostgresql"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "jdbcsqlite3"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "postgis"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "mysql2"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "mysql2_makara"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "mysql2spatial"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "postgis"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "postgresql"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "postgresql"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "seamless_database_pool"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "spatialite"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ENV["ARE_DB"] = "sqlite3"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV["ARE_DB"] = "trilogy"
4
+
5
+ if ENV['AR_VERSION'].to_f <= 7.0
6
+ require "activerecord-trilogy-adapter"
7
+ require "trilogy_adapter/connection"
8
+ ActiveRecord::Base.extend TrilogyAdapter::Connection
9
+ end
@@ -8,6 +8,7 @@ common: &common
8
8
  mysql2: &mysql2
9
9
  <<: *common
10
10
  adapter: mysql2
11
+ host: mysql
11
12
 
12
13
  mysql2spatial:
13
14
  <<: *mysql2
@@ -19,6 +20,7 @@ postgresql: &postgresql
19
20
  <<: *common
20
21
  username: postgres
21
22
  adapter: postgresql
23
+ host: postgresql
22
24
  min_messages: warning
23
25
 
24
26
  postresql_makara:
@@ -50,3 +52,8 @@ sqlite3: &sqlite3
50
52
 
51
53
  spatialite:
52
54
  <<: *sqlite3
55
+
56
+ trilogy:
57
+ <<: *common
58
+ adapter: trilogy
59
+ host: mysql
@@ -1,7 +1,8 @@
1
1
  common: &common
2
2
  username: root
3
- password:
3
+ password: root
4
4
  encoding: utf8
5
+ collation: utf8_general_ci
5
6
  host: localhost
6
7
  database: activerecord_import_test
7
8
 
@@ -37,6 +38,7 @@ oracle:
37
38
  postgresql: &postgresql
38
39
  <<: *common
39
40
  username: postgres
41
+ password: postgres
40
42
  adapter: postgresql
41
43
  min_messages: warning
42
44
 
@@ -64,3 +66,7 @@ sqlite3: &sqlite3
64
66
 
65
67
  spatialite:
66
68
  <<: *sqlite3
69
+
70
+ trilogy:
71
+ <<: *common
72
+ adapter: trilogy
data/test/import_test.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper', __FILE__)
2
4
 
3
5
  describe "#import" do
@@ -159,6 +161,25 @@ describe "#import" do
159
161
  Tag.import columns, values, validate: false
160
162
  end
161
163
  end
164
+
165
+ it "should import models that are required to belong to models with composite primary keys" do
166
+ tag = Tag.create!(tag_id: 1, publisher_id: 1, tag: 'Mystery')
167
+ valid_tag_alias = TagAlias.new(tag_id: tag.tag_id, parent_id: tag.publisher_id, alias: 'Detective')
168
+ invalid_tag_aliases = [
169
+ TagAlias.new(tag_id: nil, parent_id: nil, alias: 'Detective'),
170
+ TagAlias.new(tag_id: tag.tag_id, parent_id: nil, alias: 'Detective'),
171
+ TagAlias.new(tag_id: nil, parent_id: tag.publisher_id, alias: 'Detective'),
172
+ ]
173
+
174
+ assert_difference "TagAlias.count", +1 do
175
+ TagAlias.import [valid_tag_alias]
176
+ end
177
+ invalid_tag_aliases.each do |invalid_tag_alias|
178
+ assert_no_difference "TagAlias.count" do
179
+ TagAlias.import [invalid_tag_alias]
180
+ end
181
+ end
182
+ end
162
183
  end
163
184
  end
164
185
 
@@ -169,7 +190,17 @@ describe "#import" do
169
190
  assert_difference "Dictionary.count", +1 do
170
191
  Dictionary.import dictionaries
171
192
  end
172
- assert_equal "Dictionary", Dictionary.first.type
193
+ assert_equal "Dictionary", Dictionary.last.type
194
+ end
195
+
196
+ it "should import arrays successfully" do
197
+ columns = [:author_name, :title]
198
+ values = [["Noah Webster", "Webster's Dictionary"]]
199
+
200
+ assert_difference "Dictionary.count", +1 do
201
+ Dictionary.import columns, values
202
+ end
203
+ assert_equal "Dictionary", Dictionary.last.type
173
204
  end
174
205
  end
175
206
 
@@ -252,6 +283,16 @@ describe "#import" do
252
283
  end
253
284
  end
254
285
 
286
+ it "should index the failed instances by their poistion in the set if `track_failures` is true" do
287
+ index_offset = valid_values.length
288
+ results = Topic.import columns, valid_values + invalid_values, validate: true, track_validation_failures: true
289
+ assert_equal invalid_values.size, results.failed_instances.size
290
+ invalid_values.each_with_index do |value_set, index|
291
+ assert_equal index + index_offset, results.failed_instances[index].first
292
+ assert_equal value_set.first, results.failed_instances[index].last.title
293
+ end
294
+ end
295
+
255
296
  it "should set ids in valid models if adapter supports setting primary key of imported objects" do
256
297
  if ActiveRecord::Base.supports_setting_primary_key_of_imported_objects?
257
298
  Topic.import (invalid_models + valid_models), validate: true
@@ -395,6 +436,15 @@ describe "#import" do
395
436
  assert_equal 3, result.num_inserts if Topic.supports_import?
396
437
  end
397
438
  end
439
+
440
+ it "should accept and call an optional callable to run after each batch" do
441
+ lambda_called = 0
442
+
443
+ my_proc = ->(_row_count, _batches, _batch, _duration) { lambda_called += 1 }
444
+ Topic.import Build(10, :topics), batch_size: 4, batch_progress: my_proc
445
+
446
+ assert_equal 3, lambda_called
447
+ end
398
448
  end
399
449
 
400
450
  context "with :synchronize option" do
@@ -526,7 +576,11 @@ describe "#import" do
526
576
  context "when the timestamps columns are present" do
527
577
  setup do
528
578
  @existing_book = Book.create(title: "Fell", author_name: "Curry", publisher: "Bayer", created_at: 2.years.ago.utc, created_on: 2.years.ago.utc, updated_at: 2.years.ago.utc, updated_on: 2.years.ago.utc)
529
- ActiveRecord::Base.default_timezone = :utc
579
+ if ActiveRecord.respond_to?(:default_timezone)
580
+ ActiveRecord.default_timezone = :utc
581
+ else
582
+ ActiveRecord::Base.default_timezone = :utc
583
+ end
530
584
  Timecop.freeze(time) do
531
585
  assert_difference "Book.count", +2 do
532
586
  Book.import %w(title author_name publisher created_at created_on updated_at updated_on), [["LDAP", "Big Bird", "Del Rey", nil, nil, nil, nil], [@existing_book.title, @existing_book.author_name, @existing_book.publisher, @existing_book.created_at, @existing_book.created_on, @existing_book.updated_at, @existing_book.updated_on]]
@@ -642,6 +696,14 @@ describe "#import" do
642
696
  assert_equal [val1, val2], scope.map(&column).sort
643
697
  end
644
698
 
699
+ context "for cards and decks" do
700
+ it "works when the polymorphic name is different than base class name" do
701
+ deck = Deck.create(id: 1, name: 'test')
702
+ deck.cards.import [:id, :deck_type], [[1, 'PlayingCard']]
703
+ assert_equal deck.cards.first.deck_type, "PlayingCard"
704
+ end
705
+ end
706
+
645
707
  it "works importing array of hashes" do
646
708
  scope.import [{ column => val1 }, { column => val2 }]
647
709
 
@@ -900,4 +962,33 @@ describe "#import" do
900
962
  end
901
963
  end
902
964
  end
965
+ describe "importing model with after_initialize callback" do
966
+ let(:columns) { %w(name size) }
967
+ let(:valid_values) { [%w("Deer", "Small"), %w("Monkey", "Medium")] }
968
+ let(:invalid_values) do
969
+ [
970
+ { name: "giraffe", size: "Large" },
971
+ { size: "Medium" } # name is missing
972
+ ]
973
+ end
974
+ context "with validation checks turned off" do
975
+ it "should import valid data" do
976
+ Animal.import(columns, valid_values, validate: false)
977
+ assert_equal 2, Animal.count
978
+ end
979
+ it "should raise ArgumentError" do
980
+ assert_raise(ArgumentError) { Animal.import(invalid_values, validate: false) }
981
+ end
982
+ end
983
+
984
+ context "with validation checks turned on" do
985
+ it "should import valid data" do
986
+ Animal.import(columns, valid_values, validate: true)
987
+ assert_equal 2, Animal.count
988
+ end
989
+ it "should raise ArgumentError" do
990
+ assert_raise(ArgumentError) { Animal.import(invalid_values, validate: true) }
991
+ end
992
+ end
993
+ end
903
994
  end
@@ -1,5 +1,7 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../support/assertions')
3
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/import_examples')
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
4
+ require File.expand_path("#{File.dirname(__FILE__)}/../support/assertions")
5
+ require File.expand_path("#{File.dirname(__FILE__)}/../support/mysql/import_examples")
4
6
 
5
7
  should_support_mysql_import_functionality
@@ -1,4 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../support/postgresql/import_examples')
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
4
+ require File.expand_path("#{File.dirname(__FILE__)}/../support/postgresql/import_examples")
3
5
 
4
6
  should_support_postgresql_import_functionality
@@ -1,4 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../support/sqlite3/import_examples')
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
4
+ require File.expand_path("#{File.dirname(__FILE__)}/../support/sqlite3/import_examples")
3
5
 
4
6
  should_support_sqlite3_import_functionality
@@ -1,5 +1,7 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/../support/postgresql/import_examples')
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
4
+ require File.expand_path("#{File.dirname(__FILE__)}/../support/postgresql/import_examples")
3
5
 
4
6
  should_support_postgresql_import_functionality
5
7
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Account < ActiveRecord::Base
2
4
  self.locking_column = :lock
3
5
  end
data/test/models/alarm.rb CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Alarm < ActiveRecord::Base
2
4
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Animal < ActiveRecord::Base
4
+ after_initialize :validate_name_presence, if: :new_record?
5
+ def validate_name_presence
6
+ raise ArgumentError if name.nil?
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Author < ActiveRecord::Base
4
+ if ENV['AR_VERSION'].to_f >= 7.1
5
+ has_many :composite_books, query_constraints: [:id, :author_id], inverse_of: :author
6
+ end
7
+ end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bike
2
4
  def self.table_name_prefix
3
5
  'bike_'
4
6
  end
7
+
5
8
  class Maker < ActiveRecord::Base
6
9
  end
7
10
  end
data/test/models/book.rb CHANGED
@@ -1,7 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Book < ActiveRecord::Base
2
4
  belongs_to :topic, inverse_of: :books
3
- belongs_to :tag, foreign_key: [:tag_id, :parent_id]
4
-
5
+ if ENV['AR_VERSION'].to_f <= 7.0
6
+ belongs_to :tag, foreign_key: [:tag_id, :parent_id] unless ENV["SKIP_COMPOSITE_PK"]
7
+ else
8
+ belongs_to :tag, query_constraints: [:tag_id, :parent_id] unless ENV["SKIP_COMPOSITE_PK"]
9
+ end
5
10
  has_many :chapters, inverse_of: :book
6
11
  has_many :discounts, as: :discountable
7
12
  has_many :end_notes, inverse_of: :book
data/test/models/car.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Car < ActiveRecord::Base
2
4
  self.primary_key = :Name
3
5
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Card < ActiveRecord::Base
4
+ belongs_to :deck, polymorphic: true
5
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Chapter < ActiveRecord::Base
2
4
  belongs_to :book, inverse_of: :chapters
3
5
  validates :title, presence: true
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CompositeBook < ActiveRecord::Base
4
+ self.primary_key = %i[id author_id]
5
+ belongs_to :author
6
+ if ENV['AR_VERSION'].to_f <= 7.0
7
+ unless ENV["SKIP_COMPOSITE_PK"]
8
+ has_many :composite_chapters, inverse_of: :composite_book,
9
+ foreign_key: [:id, :author_id]
10
+ end
11
+ else
12
+ has_many :composite_chapters, inverse_of: :composite_book,
13
+ query_constraints: [:id, :author_id]
14
+ end
15
+
16
+ def self.sequence_name
17
+ "composite_book_id_seq"
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CompositeChapter < ActiveRecord::Base
4
+ if ENV['AR_VERSION'].to_f >= 7.1
5
+ belongs_to :composite_book, inverse_of: :composite_chapters,
6
+ query_constraints: [:composite_book_id, :author_id]
7
+ end
8
+ validates :title, presence: true
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Customer < ActiveRecord::Base
4
+ unless ENV["SKIP_COMPOSITE_PK"]
5
+ if ENV['AR_VERSION'].to_f <= 7.0
6
+ has_many :orders,
7
+ inverse_of: :customer,
8
+ primary_key: %i(account_id id),
9
+ foreign_key: %i(account_id customer_id)
10
+ else
11
+ has_many :orders,
12
+ inverse_of: :customer,
13
+ primary_key: %i(account_id id),
14
+ query_constraints: %i(account_id customer_id)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Deck < ActiveRecord::Base
4
+ has_many :cards
5
+ def self.polymorphic_name
6
+ "PlayingCard"
7
+ end
8
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'book'
2
4
 
3
5
  class Dictionary < Book
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Discount < ActiveRecord::Base
2
4
  belongs_to :discountable, polymorphic: true
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class EndNote < ActiveRecord::Base
2
4
  belongs_to :book, inverse_of: :end_notes
3
5
  validates :note, presence: true
data/test/models/group.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Group < ActiveRecord::Base
2
4
  self.table_name = 'group'
3
5
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Order < ActiveRecord::Base
4
+ unless ENV["SKIP_COMPOSITE_PK"]
5
+ if ENV['AR_VERSION'].to_f <= 7.0
6
+ belongs_to :customer,
7
+ inverse_of: :orders,
8
+ primary_key: %i(account_id id),
9
+ foreign_key: %i(account_id customer_id)
10
+ else
11
+ belongs_to :customer,
12
+ inverse_of: :orders,
13
+ primary_key: %i(account_id id),
14
+ query_constraints: %i(account_id customer_id)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PlayingCard < ActiveRecord::Base
4
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Promotion < ActiveRecord::Base
2
4
  self.primary_key = :promotion_id
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Question < ActiveRecord::Base
2
4
  has_one :rule
3
5
  end
data/test/models/rule.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Rule < ActiveRecord::Base
2
4
  belongs_to :question
3
5
  end
data/test/models/tag.rb CHANGED
@@ -1,4 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Tag < ActiveRecord::Base
2
- self.primary_keys = :tag_id, :publisher_id unless ENV["SKIP_COMPOSITE_PK"]
4
+ if ENV['AR_VERSION'].to_f <= 7.0
5
+ self.primary_keys = :tag_id, :publisher_id unless ENV["SKIP_COMPOSITE_PK"]
6
+ else
7
+ self.primary_key = [:tag_id, :publisher_id] unless ENV["SKIP_COMPOSITE_PK"]
8
+ end
9
+ self.primary_key = [:tag_id, :publisher_id] unless ENV["SKIP_COMPOSITE_PK"]
3
10
  has_many :books, inverse_of: :tag
11
+ has_many :tag_aliases, inverse_of: :tag
4
12
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TagAlias < ActiveRecord::Base
4
+ unless ENV["SKIP_COMPOSITE_PK"]
5
+ if ENV['AR_VERSION'].to_f <= 7.0
6
+ belongs_to :tag, foreign_key: [:tag_id, :parent_id], required: true
7
+ else
8
+ belongs_to :tag, query_constraints: [:tag_id, :parent_id], required: true
9
+ end
10
+ end
11
+ end
data/test/models/topic.rb CHANGED
@@ -1,4 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Topic < ActiveRecord::Base
4
+ if ENV['AR_VERSION'].to_i >= 6.0
5
+ self.ignored_columns = [:priority]
6
+ end
7
+ alias_attribute :name, :title
8
+
2
9
  validates_presence_of :author_name
3
10
  validates :title, numericality: { only_integer: true }, on: :context_test
4
11
  validates :title, uniqueness: true
data/test/models/user.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class User < ActiveRecord::Base
2
4
  has_many :user_tokens, primary_key: :name, foreign_key: :user_name
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class UserToken < ActiveRecord::Base
2
4
  belongs_to :user, primary_key: :name, foreign_key: :user_name
3
5
  validates :user, presence: true