activerecord-import 1.2.0 → 1.3.0

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
2
  SHA256:
3
- metadata.gz: b3360334cbd71089351c8211214bb4aedf0bd3e65305513b17c9fb09e3f1cf19
4
- data.tar.gz: 2b97e3a1c6c2b39970dd3bb2a00a608d6e105cddac19d3f9ebaf28f8f30ece69
3
+ metadata.gz: 815280c3b17a8ee84e54defd450a68fa532719dc8760ac001883f3df0156d689
4
+ data.tar.gz: d34ee8c4c186b172259ea4f3427a75379d08b7ae41ee67128fd870e489d2f78d
5
5
  SHA512:
6
- metadata.gz: 4585ba6ff2300d94fbd646d5f5a07cc254311cb9a47eacc7b1266eab8df5d9a53ca3018232e6c2517f05e1aef0dafaff20942bd1150ef518d688940f795bf2a9
7
- data.tar.gz: 532506d134f067323d0490a913739089e55bf17893f602c752e5e963af2d7d799f5200a72cc48e7c780992e9f82c68273dc7af308034664ba898ed5292e199c4
6
+ metadata.gz: 49c6d78cbcdc342db44497ec66f0dfe466b08124dc233996688c9443b0c455328e6d7ebc80d011c8732f7ae5b5468bd3c4f57f4abe2bb20bc26a118183cea402
7
+ data.tar.gz: 9f602bb4423fb3cc5169727d150df7eef5396954f0576f1ecf8cb168179adc625f5ef5927a4655eb8271e37d845d9e5c6b6a6a597a83cb1c268958b4f2f65375
@@ -20,13 +20,18 @@ jobs:
20
20
  fail-fast: false
21
21
  matrix:
22
22
  ruby:
23
- - 2.6
23
+ - 2.7
24
24
  env:
25
+ - AR_VERSION: 7.0
25
26
  - AR_VERSION: 6.1
26
27
  - AR_VERSION: 6.0
27
- - AR_VERSION: 5.2
28
- - AR_VERSION: 5.1
29
28
  include:
29
+ - ruby: 2.6
30
+ env:
31
+ AR_VERSION: 5.2
32
+ - ruby: 2.6
33
+ env:
34
+ AR_VERSION: 5.1
30
35
  - ruby: 2.4
31
36
  env:
32
37
  AR_VERSION: 5.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## Changes in 1.3.0
2
+
3
+ ### Fixes
4
+
5
+ * Ensure correct timestamp values are returned for models after insert. Thanks to @kos1kov via \##756.
6
+ * Restore database_version method to public scope. Thanks to @beauraF via \##753.
7
+
8
+ ### New Features
9
+
10
+ * Add support for ActiveRecord 7.0. Thanks to @nickhammond, @ryanwood, @jkowens via \##749 and \##752.
11
+ * Add support for compound foreign keys. Thanks to @Uladzimiro via \##750.
12
+ * Add support for :recursive combined with on_duplicate_key_update: :all. Thanks to @deathwish via \##746.
13
+
1
14
  ## Changes in 1.2.0
2
15
 
3
16
  ### Fixes
data/Gemfile CHANGED
@@ -26,7 +26,7 @@ platforms :ruby do
26
26
  end
27
27
 
28
28
  platforms :jruby do
29
- gem 'jdbc-mysql', '< 8', require: false
29
+ gem "jdbc-mysql"
30
30
  gem "jdbc-postgres"
31
31
  gem "activerecord-jdbcsqlite3-adapter", "~> 1.3"
32
32
  gem "activerecord-jdbcmysql-adapter", "~> 1.3"
@@ -16,8 +16,8 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.version = ActiveRecord::Import::VERSION
18
18
 
19
- gem.required_ruby_version = ">= 2.0.0"
19
+ gem.required_ruby_version = ">= 2.4.0"
20
20
 
21
- gem.add_runtime_dependency "activerecord", ">= 3.2"
21
+ gem.add_runtime_dependency "activerecord", ">= 4.2"
22
22
  gem.add_development_dependency "rake"
23
23
  end
data/gemfiles/6.1.gemfile CHANGED
@@ -1 +1,2 @@
1
1
  gem 'activerecord', '~> 6.1.0'
2
+ gem 'composite_primary_keys', '~> 13.0'
@@ -0,0 +1 @@
1
+ gem 'activerecord', '~> 7.0.0.alpha2'
@@ -203,8 +203,6 @@ module ActiveRecord::Import::PostgreSQLAdapter
203
203
  true
204
204
  end
205
205
 
206
- private
207
-
208
206
  def database_version
209
207
  defined?(postgresql_version) ? postgresql_version : super
210
208
  end
@@ -166,8 +166,6 @@ module ActiveRecord::Import::SQLite3Adapter
166
166
  exception.is_a?(ActiveRecord::StatementInvalid) && exception.to_s.include?('duplicate key')
167
167
  end
168
168
 
169
- private
170
-
171
169
  def database_version
172
170
  defined?(sqlite_version) ? sqlite_version : super
173
171
  end
@@ -34,7 +34,7 @@ module ActiveRecord::Import #:nodoc:
34
34
  @validate_callbacks = klass._validate_callbacks.dup
35
35
 
36
36
  @validate_callbacks.each_with_index do |callback, i|
37
- filter = callback.raw_filter
37
+ filter = callback.respond_to?(:raw_filter) ? callback.raw_filter : callback.filter
38
38
  next unless filter.class.name =~ /Validations::PresenceValidator/ ||
39
39
  (!@options[:validate_uniqueness] &&
40
40
  filter.is_a?(ActiveRecord::Validations::UniquenessValidator))
@@ -734,7 +734,10 @@ class ActiveRecord::Base
734
734
  set_attributes_and_mark_clean(models, return_obj, timestamps, options)
735
735
 
736
736
  # if there are auto-save associations on the models we imported that are new, import them as well
737
- import_associations(models, options.dup.merge(validate: false)) if options[:recursive]
737
+ if options[:recursive]
738
+ options[:on_duplicate_key_update] = on_duplicate_key_update unless on_duplicate_key_update.nil?
739
+ import_associations(models, options.dup.merge(validate: false))
740
+ end
738
741
  end
739
742
 
740
743
  return_obj
@@ -854,7 +857,7 @@ class ActiveRecord::Base
854
857
  model.id = id
855
858
 
856
859
  timestamps.each do |attr, value|
857
- model.send(attr + "=", value)
860
+ model.send(attr + "=", value) if model.send(attr).nil?
858
861
  end
859
862
  end
860
863
  end
@@ -908,15 +911,19 @@ class ActiveRecord::Base
908
911
  changed_columns = model.changed
909
912
  association_reflections = model.class.reflect_on_all_associations(:belongs_to)
910
913
  association_reflections.each do |association_reflection|
911
- column_name = association_reflection.foreign_key
912
914
  next if association_reflection.options[:polymorphic]
913
- next if changed_columns.include?(column_name)
914
- association = model.association(association_reflection.name)
915
- association = association.target
916
- next if association.blank? || model.public_send(column_name).present?
917
915
 
918
- association_primary_key = association_reflection.association_primary_key
919
- model.public_send("#{column_name}=", association.send(association_primary_key))
916
+ column_names = Array(association_reflection.foreign_key).map(&:to_s)
917
+ column_names.each_with_index do |column_name, column_index|
918
+ next if changed_columns.include?(column_name)
919
+
920
+ association = model.association(association_reflection.name)
921
+ association = association.target
922
+ next if association.blank? || model.public_send(column_name).present?
923
+
924
+ association_primary_key = Array(association_reflection.association_primary_key)[column_index]
925
+ model.public_send("#{column_name}=", association.send(association_primary_key))
926
+ end
920
927
  end
921
928
  end
922
929
 
@@ -929,8 +936,9 @@ class ActiveRecord::Base
929
936
  associated_objects_by_class = {}
930
937
  models.each { |model| find_associated_objects_for_import(associated_objects_by_class, model) }
931
938
 
932
- # :on_duplicate_key_update and :returning not supported for associations
933
- options.delete(:on_duplicate_key_update)
939
+ # :on_duplicate_key_update only supported for all fields
940
+ options.delete(:on_duplicate_key_update) unless options[:on_duplicate_key_update] == :all
941
+ # :returning not supported for associations
934
942
  options.delete(:returning)
935
943
 
936
944
  associated_objects_by_class.each_value do |associations|
@@ -1029,7 +1037,12 @@ class ActiveRecord::Base
1029
1037
  end
1030
1038
 
1031
1039
  # use tz as set in ActiveRecord::Base
1032
- timestamp = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
1040
+ default_timezone = if ActiveRecord.respond_to?(:default_timezone)
1041
+ ActiveRecord.default_timezone
1042
+ else
1043
+ ActiveRecord::Base.default_timezone
1044
+ end
1045
+ timestamp = default_timezone == :utc ? Time.now.utc : Time.now
1033
1046
 
1034
1047
  [:create, :update].each do |action|
1035
1048
  timestamp_columns[action].each do |column|
@@ -39,7 +39,7 @@ module ActiveRecord # :nodoc:
39
39
 
40
40
  next unless matched_instance
41
41
 
42
- instance.send :clear_association_cache
42
+ instance.instance_variable_set :@association_cache, {}
43
43
  instance.send :clear_aggregation_cache if instance.respond_to?(:clear_aggregation_cache, true)
44
44
  instance.instance_variable_set :@attributes, matched_instance.instance_variable_get(:@attributes)
45
45
 
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Import
3
- VERSION = "1.2.0".freeze
3
+ VERSION = "1.3.0".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,6 @@
1
+ class Customer < ActiveRecord::Base
2
+ has_many :orders,
3
+ inverse_of: :customer,
4
+ primary_key: %i(account_id id),
5
+ foreign_key: %i(account_id customer_id)
6
+ end
@@ -0,0 +1,6 @@
1
+ class Order < ActiveRecord::Base
2
+ belongs_to :customer,
3
+ inverse_of: :orders,
4
+ primary_key: %i(account_id id),
5
+ foreign_key: %i(account_id customer_id)
6
+ end
@@ -205,4 +205,15 @@ ActiveRecord::Schema.define do
205
205
  );
206
206
  ).split.join(' ').strip
207
207
  end
208
+
209
+ create_table :customers, force: :cascade do |t|
210
+ t.integer :account_id
211
+ t.string :name
212
+ end
213
+
214
+ create_table :orders, force: :cascade do |t|
215
+ t.integer :account_id
216
+ t.integer :customer_id
217
+ t.integer :amount
218
+ end
208
219
  end
@@ -290,6 +290,30 @@ def should_support_postgresql_import_functionality
290
290
  assert_equal(binary_value, Alarm.first.secret_key)
291
291
  end
292
292
  end
293
+
294
+ unless ENV["SKIP_COMPOSITE_PK"]
295
+ describe "with composite foreign keys" do
296
+ let(:account_id) { 555 }
297
+ let(:customer) { Customer.new(account_id: account_id, name: "foo") }
298
+ let(:order) { Order.new(account_id: account_id, amount: 100, customer: customer) }
299
+
300
+ it "imports and correctly maps foreign keys" do
301
+ assert_difference "Customer.count", +1 do
302
+ Customer.import [customer]
303
+ end
304
+
305
+ assert_difference "Order.count", +1 do
306
+ Order.import [order]
307
+ end
308
+
309
+ db_customer = Customer.last
310
+ db_order = Order.last
311
+
312
+ assert_equal db_customer.orders.last, db_order
313
+ assert_not_equal db_order.customer_id, nil
314
+ end
315
+ end
316
+ end
293
317
  end
294
318
 
295
319
  def should_support_postgresql_upsert_functionality
@@ -176,7 +176,7 @@ def should_support_recursive_import
176
176
  end
177
177
  end
178
178
 
179
- # If adapter supports on_duplicate_key_update, it is only applied to top level models so that SQL with invalid
179
+ # If adapter supports on_duplicate_key_update and specific columns are specified, it is only applied to top level models so that SQL with invalid
180
180
  # columns, keys, etc isn't generated for child associations when doing recursive import
181
181
  if ActiveRecord::Base.connection.supports_on_duplicate_key_update?
182
182
  describe "on_duplicate_key_update" do
@@ -190,6 +190,26 @@ def should_support_recursive_import
190
190
  end
191
191
  end
192
192
  end
193
+
194
+ context "when :all fields are updated" do
195
+ setup do
196
+ Topic.import new_topics, recursive: true
197
+ end
198
+
199
+ it "updates associated objects" do
200
+ new_author_name = 'Richard Bachman'
201
+ topic = new_topics.first
202
+ topic.books.each do |book|
203
+ book.author_name = new_author_name
204
+ end
205
+ assert_nothing_raised do
206
+ Topic.import new_topics, recursive: true, on_duplicate_key_update: :all
207
+ end
208
+ Topic.find(topic.id).books.each do |book|
209
+ assert_equal new_author_name, book.author_name
210
+ end
211
+ end
212
+ end
193
213
  end
194
214
  end
195
215
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-import
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Dennis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-17 00:00:00.000000000 Z
11
+ date: 2021-12-17 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: '3.2'
19
+ version: '4.2'
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: '3.2'
26
+ version: '4.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -68,15 +68,13 @@ files:
68
68
  - benchmarks/models/test_memory.rb
69
69
  - benchmarks/models/test_myisam.rb
70
70
  - benchmarks/schema/mysql2_schema.rb
71
- - gemfiles/3.2.gemfile
72
- - gemfiles/4.0.gemfile
73
- - gemfiles/4.1.gemfile
74
71
  - gemfiles/4.2.gemfile
75
72
  - gemfiles/5.0.gemfile
76
73
  - gemfiles/5.1.gemfile
77
74
  - gemfiles/5.2.gemfile
78
75
  - gemfiles/6.0.gemfile
79
76
  - gemfiles/6.1.gemfile
77
+ - gemfiles/7.0.gemfile
80
78
  - lib/activerecord-import.rb
81
79
  - lib/activerecord-import/active_record/adapters/abstract_adapter.rb
82
80
  - lib/activerecord-import/active_record/adapters/jdbcmysql_adapter.rb
@@ -128,11 +126,13 @@ files:
128
126
  - test/models/car.rb
129
127
  - test/models/card.rb
130
128
  - test/models/chapter.rb
129
+ - test/models/customer.rb
131
130
  - test/models/deck.rb
132
131
  - test/models/dictionary.rb
133
132
  - test/models/discount.rb
134
133
  - test/models/end_note.rb
135
134
  - test/models/group.rb
135
+ - test/models/order.rb
136
136
  - test/models/playing_card.rb
137
137
  - test/models/promotion.rb
138
138
  - test/models/question.rb
@@ -174,7 +174,7 @@ homepage: https://github.com/zdennis/activerecord-import
174
174
  licenses:
175
175
  - MIT
176
176
  metadata: {}
177
- post_install_message:
177
+ post_install_message:
178
178
  rdoc_options: []
179
179
  require_paths:
180
180
  - lib
@@ -182,15 +182,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
182
  requirements:
183
183
  - - ">="
184
184
  - !ruby/object:Gem::Version
185
- version: 2.0.0
185
+ version: 2.4.0
186
186
  required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  requirements:
188
188
  - - ">="
189
189
  - !ruby/object:Gem::Version
190
190
  version: '0'
191
191
  requirements: []
192
- rubygems_version: 3.0.9
193
- signing_key:
192
+ rubygems_version: 3.0.3
193
+ signing_key:
194
194
  specification_version: 4
195
195
  summary: Bulk insert extension for ActiveRecord
196
196
  test_files:
@@ -222,11 +222,13 @@ test_files:
222
222
  - test/models/car.rb
223
223
  - test/models/card.rb
224
224
  - test/models/chapter.rb
225
+ - test/models/customer.rb
225
226
  - test/models/deck.rb
226
227
  - test/models/dictionary.rb
227
228
  - test/models/discount.rb
228
229
  - test/models/end_note.rb
229
230
  - test/models/group.rb
231
+ - test/models/order.rb
230
232
  - test/models/playing_card.rb
231
233
  - test/models/promotion.rb
232
234
  - test/models/question.rb
data/gemfiles/3.2.gemfile DELETED
@@ -1,2 +0,0 @@
1
- gem 'activerecord', '~> 3.2.0'
2
- gem 'composite_primary_keys', '~> 5.0'
data/gemfiles/4.0.gemfile DELETED
@@ -1,2 +0,0 @@
1
- gem 'activerecord', '~> 4.0.0'
2
- gem 'composite_primary_keys', '~> 6.0'
data/gemfiles/4.1.gemfile DELETED
@@ -1,2 +0,0 @@
1
- gem 'activerecord', '~> 4.1.0'
2
- gem 'composite_primary_keys', '~> 7.0'