activerecord-import 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/lib/activerecord-import/adapters/postgresql_adapter.rb +2 -2
- data/lib/activerecord-import/import.rb +7 -17
- data/lib/activerecord-import/version.rb +1 -1
- data/test/import_test.rb +5 -0
- data/test/schema/postgresql_schema.rb +2 -0
- data/test/support/postgresql/import_examples.rb +13 -0
- data/test/support/shared_examples/recursive_import.rb +29 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 641c8875527982cb5d4657eac796783d8f3875074ae0aff972fb675ad116d785
|
4
|
+
data.tar.gz: 613b7410d4c4134a3827462b9e41dde7cfd47fbce6b1079b20498d9aa3f36062
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d25ac8e6af2a1f74df64431002a081afa5a3aebe7b21c3f08fb4b35774579dd59c3bffbbdd5300c6a03b8d709b02a88fa36aa0aff9c5811e1b630dbd46fc5911
|
7
|
+
data.tar.gz: 248155a8c56f09acf2ad22e178d29e1c93a4eac272c3a41f77d8f426304f4b1c63f62642360bde76a41683ec50a594a14d3ac4b9b09981788239b670bbfa0cfa
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## Changes in 1.0.1
|
2
|
+
|
3
|
+
### Fixes
|
4
|
+
|
5
|
+
* Raise an error with a helpful message if array of values exceeds the number of
|
6
|
+
columns for a table. Thanks to @golddranks via \#589.
|
7
|
+
* Properly check if model responds to import before creating alias.
|
8
|
+
Thanks to @jcw- via \#591.
|
9
|
+
* No longer pass :returning option to child associations on recursive
|
10
|
+
import. Thanks to @dmitriy-kiriyenko via \#595.
|
11
|
+
* Fix import issue for models with Postgresql json/jsonb fields. Thanks
|
12
|
+
to @stokarenko via \#594.
|
13
|
+
* Fix issue importing models with timestamps that contain timezone
|
14
|
+
information. Thaks to @dekaikiwi, @jkowens via \#598.
|
15
|
+
* Ignore :no_returning when using :recursive option. Thanks to @dgollahon, @jkowens
|
16
|
+
via \#599.
|
17
|
+
|
1
18
|
## Changes in 1.0.0
|
2
19
|
|
3
20
|
### New Features
|
@@ -19,7 +19,7 @@ module ActiveRecord::Import::PostgreSQLAdapter
|
|
19
19
|
sql2insert = base_sql + values.join( ',' ) + post_sql
|
20
20
|
|
21
21
|
columns = returning_columns(options)
|
22
|
-
if columns.blank? || options[:no_returning]
|
22
|
+
if columns.blank? || (options[:no_returning] && !options[:recursive])
|
23
23
|
insert( sql2insert, *args )
|
24
24
|
else
|
25
25
|
returned_values = if columns.size > 1
|
@@ -80,7 +80,7 @@ module ActiveRecord::Import::PostgreSQLAdapter
|
|
80
80
|
sql += super(table_name, options)
|
81
81
|
|
82
82
|
columns = returning_columns(options)
|
83
|
-
unless columns.blank? || options[:no_returning]
|
83
|
+
unless columns.blank? || (options[:no_returning] && !options[:recursive])
|
84
84
|
sql << " RETURNING \"#{columns.join('", "')}\""
|
85
85
|
end
|
86
86
|
|
@@ -528,7 +528,7 @@ class ActiveRecord::Base
|
|
528
528
|
import_helper(*args)
|
529
529
|
end
|
530
530
|
end
|
531
|
-
alias import bulk_import unless respond_to? :import
|
531
|
+
alias import bulk_import unless ActiveRecord::Base.respond_to? :import
|
532
532
|
|
533
533
|
# Imports a collection of values if all values are valid. Import fails at the
|
534
534
|
# first encountered validation error and raises ActiveRecord::RecordInvalid
|
@@ -540,7 +540,7 @@ class ActiveRecord::Base
|
|
540
540
|
|
541
541
|
bulk_import(*args, options)
|
542
542
|
end
|
543
|
-
alias import! bulk_import! unless respond_to? :import!
|
543
|
+
alias import! bulk_import! unless ActiveRecord::Base.respond_to? :import!
|
544
544
|
|
545
545
|
def import_helper( *args )
|
546
546
|
options = { validate: true, timestamps: true }
|
@@ -574,15 +574,6 @@ class ActiveRecord::Base
|
|
574
574
|
end
|
575
575
|
end
|
576
576
|
|
577
|
-
default_values = column_defaults
|
578
|
-
stored_attrs = respond_to?(:stored_attributes) ? stored_attributes : {}
|
579
|
-
serialized_attrs = if defined?(ActiveRecord::Type::Serialized)
|
580
|
-
attrs = column_names.select { |c| type_for_attribute(c.to_s).class == ActiveRecord::Type::Serialized }
|
581
|
-
Hash[attrs.map { |a| [a, nil] }]
|
582
|
-
else
|
583
|
-
serialized_attributes
|
584
|
-
end
|
585
|
-
|
586
577
|
update_attrs = if record_timestamps && options[:timestamps]
|
587
578
|
if respond_to?(:timestamp_attributes_for_update, true)
|
588
579
|
send(:timestamp_attributes_for_update).map(&:to_sym)
|
@@ -608,12 +599,8 @@ class ActiveRecord::Base
|
|
608
599
|
update_attrs && update_attrs.include?(name.to_sym) &&
|
609
600
|
!model.send("#{name}_changed?")
|
610
601
|
nil
|
611
|
-
elsif stored_attrs.key?(name.to_sym) ||
|
612
|
-
serialized_attrs.key?(name.to_s) ||
|
613
|
-
default_values[name.to_s]
|
614
|
-
model.read_attribute(name.to_s)
|
615
602
|
else
|
616
|
-
model.
|
603
|
+
model.read_attribute(name.to_s)
|
617
604
|
end
|
618
605
|
end
|
619
606
|
end
|
@@ -904,8 +891,9 @@ class ActiveRecord::Base
|
|
904
891
|
associated_objects_by_class = {}
|
905
892
|
models.each { |model| find_associated_objects_for_import(associated_objects_by_class, model) }
|
906
893
|
|
907
|
-
# :on_duplicate_key_update not supported for associations
|
894
|
+
# :on_duplicate_key_update and :returning not supported for associations
|
908
895
|
options.delete(:on_duplicate_key_update)
|
896
|
+
options.delete(:returning)
|
909
897
|
|
910
898
|
associated_objects_by_class.each_value do |associations|
|
911
899
|
associations.each_value do |associated_records|
|
@@ -976,6 +964,8 @@ class ActiveRecord::Base
|
|
976
964
|
val = column.type_cast(val) unless column.type.to_sym == :binary
|
977
965
|
connection_memo.quote(val, column)
|
978
966
|
end
|
967
|
+
else
|
968
|
+
raise ArgumentError, "Number of values (#{arr.length}) exceeds number of columns (#{columns.length})"
|
979
969
|
end
|
980
970
|
end
|
981
971
|
"(#{my_values.join(',')})"
|
data/test/import_test.rb
CHANGED
@@ -17,6 +17,11 @@ describe "#import" do
|
|
17
17
|
assert_equal error.message, "Last argument should be a two dimensional array '[[]]'. First element in array was a String"
|
18
18
|
end
|
19
19
|
|
20
|
+
it "warns you that you're passing more data than you ought to" do
|
21
|
+
error = assert_raise(ArgumentError) { Topic.import %w(title author_name), [['Author #1', 'Book #1', 0]] }
|
22
|
+
assert_equal error.message, "Number of values (8) exceeds number of columns (7)"
|
23
|
+
end
|
24
|
+
|
20
25
|
it "should not produce an error when importing empty arrays" do
|
21
26
|
assert_nothing_raised do
|
22
27
|
Topic.import []
|
@@ -8,6 +8,7 @@ ActiveRecord::Schema.define do
|
|
8
8
|
t.text :preferences
|
9
9
|
|
10
10
|
if t.respond_to?(:json)
|
11
|
+
t.json :pure_json_data
|
11
12
|
t.json :data
|
12
13
|
else
|
13
14
|
t.text :data
|
@@ -20,6 +21,7 @@ ActiveRecord::Schema.define do
|
|
20
21
|
end
|
21
22
|
|
22
23
|
if t.respond_to?(:jsonb)
|
24
|
+
t.jsonb :pure_jsonb_data
|
23
25
|
t.jsonb :settings
|
24
26
|
t.jsonb :json_data, null: false, default: {}
|
25
27
|
else
|
@@ -234,6 +234,19 @@ def should_support_postgresql_import_functionality
|
|
234
234
|
assert_equal({}, Vendor.first.json_data)
|
235
235
|
end
|
236
236
|
end
|
237
|
+
|
238
|
+
%w(json jsonb).each do |json_type|
|
239
|
+
describe "with pure #{json_type} fields" do
|
240
|
+
let(:data) { { a: :b } }
|
241
|
+
let(:json_field_name) { "pure_#{json_type}_data" }
|
242
|
+
it "imports the values from saved records" do
|
243
|
+
vendor = Vendor.create!(name: 'Vendor 1', json_field_name => data)
|
244
|
+
|
245
|
+
Vendor.import [vendor], on_duplicate_key_update: [json_field_name]
|
246
|
+
assert_equal(data.as_json, vendor.reload[json_field_name])
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
237
250
|
end
|
238
251
|
|
239
252
|
describe "with binary field" do
|
@@ -183,5 +183,34 @@ def should_support_recursive_import
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
end
|
186
|
+
|
187
|
+
# If returning option is provided, it is only applied to top level models so that SQL with invalid
|
188
|
+
# columns, keys, etc isn't generated for child associations when doing recursive import
|
189
|
+
describe "returning" do
|
190
|
+
let(:new_topics) { Build(1, :topic_with_book) }
|
191
|
+
|
192
|
+
it "imports objects with associations" do
|
193
|
+
assert_difference "Topic.count", +1 do
|
194
|
+
Topic.import new_topics, recursive: true, returning: [:content], validate: false
|
195
|
+
new_topics.each do |topic|
|
196
|
+
assert_not_nil topic.id
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# If no returning option is provided, it is ignored
|
203
|
+
describe "no returning" do
|
204
|
+
let(:new_topics) { Build(1, :topic_with_book) }
|
205
|
+
|
206
|
+
it "is ignored and imports objects with associations" do
|
207
|
+
assert_difference "Topic.count", +1 do
|
208
|
+
Topic.import new_topics, recursive: true, no_returning: true, validate: false
|
209
|
+
new_topics.each do |topic|
|
210
|
+
assert_not_nil topic.id
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
186
215
|
end
|
187
216
|
end
|
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.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Dennis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|