active_record_importer 0.3.0 → 0.4.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
  SHA1:
3
- metadata.gz: 0b0c2019e863558605d2703fb80890c8ba209192
4
- data.tar.gz: 480be20d7fc0440427e4107f7b50e7e19572ad81
3
+ metadata.gz: 71fdf968e3955c0ad63d10e6bab1f97ca4554aea
4
+ data.tar.gz: 891b854bfd76d3ea41c2596a03af4a4494e2c470
5
5
  SHA512:
6
- metadata.gz: f9191b603ceb3e77bff828ac70ad0a9301b854a1956cc1ef218e00177c2f8d5b20b0722e98bcc99cb9f99663126e29e53d3b57eebe60d14c88eb248008092441
7
- data.tar.gz: 4be44dcf15fcd9a9981ff0942c63a1a1e6d21691cf27832cb3d3755a78636f4fe79193fbe26eb5bb4ccc437cbd0e6c0ab5583d73e37f25e67e78b1a8d7d53265
6
+ metadata.gz: bbd93f935866c4ba427e942ca90fe0d2012df09cf7d064ad44642cfb981cb22f9c03cc541a0a16b71a0c0d64ecef3705e61c056e34e501a963689ce07e25a123
7
+ data.tar.gz: 8235e2a1afb32b3d4cf689c08afbeb478b88034dcd14a90cff9ecd437451493b40a38f6c672ad266a141f6f922d55b78377ddf0374a1a486e31df14587c676e0
data/README.md CHANGED
@@ -25,9 +25,10 @@ Or install it yourself as:
25
25
  $ gem install active_record_importer
26
26
 
27
27
  ## Usage
28
- ### For version 0.3.0
28
+ ### For version 0.4.0
29
29
 
30
- For the newest version (0.3.0), you don't have to create Import table/model and controller.
30
+ For the newest version (0.4.0), you don't have to create Import table/model and controller.
31
+ I already fixed the errors when there's no Import table/model on version 0.3.0.
31
32
  You just need to add the `acts_as_importable` in your model you want to be importable, and you may now run:
32
33
 
33
34
  ```ruby
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['kapitan_03@yahoo.com']
11
11
 
12
12
  spec.summary = 'Active Record Importer'
13
- spec.description = 'Smart gem for importing rails models'
13
+ spec.description = 'Smart gem for importing CSV files to ActiveRecord models'
14
14
  spec.homepage = 'https://github.com/michaelnera/active_record_importer'
15
15
  spec.license = 'MIT'
16
16
 
@@ -2,10 +2,9 @@ module ActiveRecordImporter
2
2
  class BatchImporter
3
3
  include Virtus.model
4
4
 
5
- attribute :import, Import
6
5
  attribute :importable
6
+ attribute :import
7
7
  attribute :data, Array, default: []
8
- attribute :failed_file, FailedFileBuilder, default: :initialize_failed_file
9
8
 
10
9
  def process!
11
10
  @imported_count, @failed_count = 0, 0
@@ -16,16 +15,10 @@ module ActiveRecordImporter
16
15
  end
17
16
 
18
17
  set_import_count
19
- finalize_batch_import
20
18
  end
21
19
 
22
20
  private
23
21
 
24
- def initialize_failed_file
25
- return unless import
26
- FailedFileBuilder.new(import)
27
- end
28
-
29
22
  def process_row(row_attrs)
30
23
  processor =
31
24
  DataProcessor.new(
@@ -35,7 +28,7 @@ module ActiveRecordImporter
35
28
  )
36
29
  return @imported_count += 1 if processor.process
37
30
 
38
- collect_failed_rows(row_attrs, processor.row_errors)
31
+ write_failed_row(row_attrs, processor.row_errors)
39
32
  @failed_count += 1
40
33
  end
41
34
 
@@ -46,14 +39,14 @@ module ActiveRecordImporter
46
39
  Import.update_counters(import.id, failed_rows: @failed_count)
47
40
  end
48
41
 
49
- def collect_failed_rows(row_attrs, errors)
50
- return puts errors.inspect unless failed_file
51
- @failed_file.failed_rows << row_attrs.merge(import_errors: errors)
42
+ def failed_file
43
+ return unless import.present? || import.respond_to?(:failed_file)
44
+ @failed_file ||= FailedFileBuilder.new(import)
52
45
  end
53
46
 
54
- def finalize_batch_import
55
- return unless failed_file
56
- @failed_file.build
47
+ def write_failed_row(row_attrs, errors)
48
+ return puts errors.inspect unless failed_file
49
+ failed_file.write(row_attrs.merge(import_errors: errors))
57
50
  end
58
51
 
59
52
  delegate :importer_options, to: :importable
@@ -2,8 +2,8 @@ module ActiveRecordImporter
2
2
  class DataProcessor
3
3
  include Virtus.model
4
4
 
5
- attribute :import, Import
6
5
  attribute :importable, Class
6
+ attribute :import
7
7
  attribute :insert_method, String, default: :set_insert_method
8
8
  attribute :row_attrs, Hash
9
9
  attribute :instance_attrs, Hash
@@ -2,13 +2,14 @@ module ActiveRecordImporter
2
2
  class Dispatcher
3
3
  include Virtus.model
4
4
 
5
- attribute :import, Import
6
5
  attribute :importable, Class
7
6
  attribute :execute, Boolean, default: true
7
+ attribute :import
8
8
  attribute :import_file
9
9
 
10
10
  def call
11
11
  divide_and_conquer
12
+ create_import_failed_file
12
13
  end
13
14
 
14
15
  private
@@ -19,6 +20,7 @@ module ActiveRecordImporter
19
20
  queue_or_execute(collection)
20
21
  end
21
22
  end
23
+
22
24
  true
23
25
  end
24
26
 
@@ -45,8 +47,36 @@ module ActiveRecordImporter
45
47
  ).process!
46
48
  end
47
49
 
48
- def queue(collection)
50
+ def queue(_collection)
49
51
  # To follow
50
52
  end
53
+
54
+ def create_import_failed_file
55
+ return if import.nil? || !File.exists?(temp_failed_file_path)
56
+ File.open(temp_failed_file_path) do |file|
57
+ import.failed_file = file
58
+
59
+ # I forced to save it as 'text/csv' because
60
+ # the file is being saved as 'text/x-pascal'
61
+ # and I still have no idea why?!?
62
+
63
+ import.failed_file_content_type = 'text/csv'
64
+ import.save!
65
+ end
66
+
67
+ destroy_temp_failed_file
68
+ end
69
+
70
+ def destroy_temp_failed_file
71
+ FileUtils.rm(temp_failed_file_path)
72
+ end
73
+
74
+ def temp_failed_file_path
75
+ "/tmp/#{target_file_name}"
76
+ end
77
+
78
+ def target_file_name
79
+ "failed_file_#{import.id}.csv"
80
+ end
51
81
  end
52
82
  end
@@ -5,74 +5,31 @@ module ActiveRecordImporter
5
5
 
6
6
  def initialize(import)
7
7
  @import = import
8
- @failed_rows = []
9
8
  end
10
-
11
- def build
12
- return if failed_rows.blank?
13
9
 
14
- create_or_append_to_csv
15
- create_import_failed_file
16
- destroy_temp_file
17
- end
18
-
19
- private
10
+ def write(failed_row = {})
11
+ return if failed_row.blank?
20
12
 
21
- def create_or_append_to_csv
22
- if import.failed_file.present?
23
- append_rows_to_file
13
+ if File.exists?(temp_failed_file_path)
14
+ File.open(temp_failed_file_path, 'a') do |file|
15
+ file.write failed_row.values.to_csv
16
+ end
24
17
  else
25
- write_csv_file
26
- end
27
- end
28
-
29
- def write_csv_file
30
- CSV.open(temp_file_path, 'wb') do |csv|
31
- csv << failed_rows.first.keys
32
- insert_failed_rows(csv)
18
+ File.open(temp_failed_file_path, 'w') do |file|
19
+ file.write failed_row.keys
20
+ file.write failed_row.values.to_csv
21
+ end
33
22
  end
34
23
  end
35
24
 
36
- def append_rows_to_file
37
- return if import.failed_file.blank?
38
- CSV.open(import.failed_file_path, 'a+') do |csv|
39
- insert_failed_rows(csv)
40
- end
41
- end
42
-
43
-
44
- def insert_failed_rows(csv)
45
- failed_rows.each do |hash|
46
- csv << hash.values
47
- end
48
- end
49
-
50
- def destroy_temp_file
51
- return unless File.exists?(temp_file_path)
52
- FileUtils.rm(temp_file_path)
53
- end
25
+ private
54
26
 
55
- def temp_file_path
27
+ def temp_failed_file_path
56
28
  "/tmp/#{target_file_name}"
57
29
  end
58
30
 
59
31
  def target_file_name
60
32
  "failed_file_#{import.id}.csv"
61
33
  end
62
-
63
- def create_import_failed_file
64
- return if import.failed_file.present?
65
- File.open(temp_file_path) do |file|
66
- import.failed_file = file
67
-
68
- # I forced to save it as 'text/csv' because
69
- # the file is being saved as 'text/x-pascal'
70
- # and I still have no idea why?!?
71
-
72
- import.failed_file_content_type = 'text/csv'
73
- import.save!
74
- end
75
-
76
- end
77
34
  end
78
35
  end
@@ -22,9 +22,9 @@ module ActiveRecordImporter
22
22
  ##
23
23
  def acts_as_importable(options = {})
24
24
  @@importer_options = OptionsBuilder.build(options.merge(allowed_columns_hash(options)))
25
- ::IMPORTABLES << self.name unless ::IMPORTABLES.include?(self.name)
26
25
 
27
26
  include ActiveRecordImporter::Importable::InstanceMethods
27
+ extend ActiveRecordImporter::Importable::SingletonMethods
28
28
  end
29
29
 
30
30
  def importer_options
@@ -32,7 +32,7 @@ module ActiveRecordImporter
32
32
  end
33
33
 
34
34
  def importable?
35
- ::IMPORTABLES.include?(self.name)
35
+ false
36
36
  end
37
37
 
38
38
  ##
@@ -121,5 +121,11 @@ module ActiveRecordImporter
121
121
  @importing ||= false
122
122
  end
123
123
  end
124
+
125
+ module SingletonMethods
126
+ def importable?
127
+ true
128
+ end
129
+ end
124
130
  end
125
131
  end
@@ -20,7 +20,7 @@ module ActiveRecordImporter
20
20
  attribute :remove_empty_values, Boolean, default: false
21
21
  attribute :comment_regexp, Regexp, default: Regexp.new(/^#=>/)
22
22
  attribute :force_utf8, Boolean, default: true
23
- attribute :chunk_size, Integer, default: 500
23
+ attribute :chunk_size, Integer, default: nil
24
24
  attribute :col_sep, String, default: ','
25
25
  end
26
26
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordImporter
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_importer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Nera
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-27 00:00:00.000000000 Z
11
+ date: 2017-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -132,7 +132,7 @@ dependencies:
132
132
  - - "~>"
133
133
  - !ruby/object:Gem::Version
134
134
  version: '4.0'
135
- description: Smart gem for importing rails models
135
+ description: Smart gem for importing CSV files to ActiveRecord models
136
136
  email:
137
137
  - kapitan_03@yahoo.com
138
138
  executables: []
@@ -191,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
191
  version: '0'
192
192
  requirements: []
193
193
  rubyforge_project:
194
- rubygems_version: 2.4.6
194
+ rubygems_version: 2.2.2
195
195
  signing_key:
196
196
  specification_version: 4
197
197
  summary: Active Record Importer