csv-importer 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9de355b09e3f3610054a0e2ca5c7f27b6e333c1c
4
- data.tar.gz: 759a79fb7217f50959c265cf433351460a21e7f4
3
+ metadata.gz: 07b837a8650d40afb4feb4be4b9d1679d4f7a41a
4
+ data.tar.gz: f74a63d0b1c65c647ca8ccd102151a2c542f1212
5
5
  SHA512:
6
- metadata.gz: 41d3f8ffff6fa2b92bf02a15c02e9713171d44c898efc929ff8daa79a6f7f9b6a9a666f586abb4874d4a7e738a58d2e2d72035fa447f2c80d5a62bf4ddefafd2
7
- data.tar.gz: 721a1e4e3b86de3e633d5c62bb7cd5f602af14e82daa2257af1d9bb88bf3ef07e3ef3201ac327434a1310467210478cce1603600b4cb7c82fa88f4b47f15d721
6
+ metadata.gz: 0b3453bf9dc18bc3dcd66b04b7901c5e68d9c66afa362d4e0ae9965dc82745a9380dd53e8d5fbdcc42cc7ab4b3501f3d1debfe2894e013b9fa08a7dc90012dcb
7
+ data.tar.gz: 633f1f1e78cb60a1dd911349ab5651d498acfb0a1ff8983f88e144a4d429de17a43d3e2bd43e12538a1a31c15edf327ccca290c908f727f06811253dc8aaf8d5
data/CHANGELOG.md CHANGED
@@ -2,7 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## Unreleased
5
+ ## [0.3.0] - 2016-02-05
6
+
7
+ ### Added
8
+
9
+ * Empty cells are now empty strings. You don't have to check for a nil
10
+ value when applying a transformation anymore.
11
+
12
+ ```ruby
13
+ # Prior to 0.3, an empty cell turns into `nil`
14
+ column :email, to: ->(email) { email.downcase unless email.nil? }
15
+
16
+ # From 0.3, an empty cell turns into `""`
17
+ column :email, to: ->(email) { email.downcase }
18
+ ```
19
+
20
+ * You can now skip an import in the `after_build` callback:
21
+
22
+ ```ruby
23
+ UserImport.new(file: csv_file) do
24
+ # Skip existing records
25
+ after_build do |user|
26
+ skip! if user.persisted?
27
+ end
28
+ end
29
+ ```
6
30
 
7
31
  ## [0.2.0] - 2015-07-24
8
32
 
@@ -41,7 +65,7 @@ UserImport.new(file: csv_file, quote_char: "'")
41
65
 
42
66
  ```ruby
43
67
  UserImport.new(file: csv_file) do
44
- after_build do
68
+ after_build do |user|
45
69
  user.import_by_user = current_user
46
70
  end
47
71
  end
data/README.md CHANGED
@@ -169,7 +169,7 @@ Now, email could also be spelled "e-mail", or "mail", or even "courriel"
169
169
  Nice, emails should be downcased though, so let's do this.
170
170
 
171
171
  ```ruby
172
- column :email, as: [/e.?mail/i, "courriel"], to: ->(email) { email.downcase if email }
172
+ column :email, as: [/e.?mail/i, "courriel"], to: ->(email) { email.downcase }
173
173
  ```
174
174
 
175
175
  If you need to do more advanced stuff, you've got access to the model:
@@ -209,7 +209,7 @@ class ImportUserCSV
209
209
 
210
210
  model User
211
211
 
212
- column :email, to: ->(email) { email.downcase if email }
212
+ column :email, to: ->(email) { email.downcase }
213
213
 
214
214
  identifier :email
215
215
  end
@@ -236,7 +236,7 @@ class ImportUserCSV
236
236
 
237
237
  model User
238
238
 
239
- column :email, to: ->(email) { email.downcase if email }
239
+ column :email, to: ->(email) { email.downcase }
240
240
 
241
241
  on_error :abort
242
242
  end
@@ -287,7 +287,7 @@ class ImportUserCSV
287
287
  column :email
288
288
 
289
289
  after_build do |user|
290
- user.name = email.split('@').first if email
290
+ user.name = email.split('@').first
291
291
  end
292
292
  end
293
293
 
@@ -314,6 +314,20 @@ UserImport.new(file: my_file) do
314
314
  end
315
315
  ```
316
316
 
317
+ ### Skip import
318
+
319
+ You can skip the import of a model by calling `skip!` in an
320
+ `after_build` block:
321
+
322
+ ```ruby
323
+ UserImport.new(file: csv_file) do
324
+ # Skip existing records
325
+ after_build do |user|
326
+ skip! if user.persisted?
327
+ end
328
+ end
329
+ ```
330
+
317
331
 
318
332
  ### Validate the header
319
333
 
@@ -13,7 +13,7 @@ module CSVImporter
13
13
  @csv_rows ||= begin
14
14
  sane_content = sanitize_content(read_content)
15
15
  separator = detect_separator(sane_content)
16
- cells = CSV.parse(sane_content, col_sep: separator, quote_char: quote_char)
16
+ cells = CSV.parse(sane_content, col_sep: separator, quote_char: quote_char, skip_blanks: true)
17
17
  sanitize_cells(cells)
18
18
  end
19
19
  end
@@ -54,11 +54,11 @@ module CSVImporter
54
54
  SEPARATORS.sort_by { |separator| csv_content.count(separator) }.last
55
55
  end
56
56
 
57
- # Strip cells
57
+ # Remove trailing white spaces and ensure we always return a string
58
58
  def sanitize_cells(rows)
59
59
  rows.map do |cells|
60
60
  cells.map do |cell|
61
- cell.strip if cell
61
+ cell ? cell.strip : ""
62
62
  end
63
63
  end
64
64
  end
@@ -21,6 +21,8 @@ module CSVImporter
21
21
  attribute :updated_rows, Array[Row], default: proc { [] }
22
22
  attribute :failed_to_create_rows, Array[Row], default: proc { [] }
23
23
  attribute :failed_to_update_rows, Array[Row], default: proc { [] }
24
+ attribute :create_skipped_rows, Array[Row], default: proc { [] }
25
+ attribute :update_skipped_rows, Array[Row], default: proc { [] }
24
26
 
25
27
  attribute :message_generator, Class, default: proc { ReportMessage }
26
28
 
@@ -11,6 +11,7 @@ module CSVImporter
11
11
  attribute :model_klass
12
12
  attribute :identifiers, Array[Symbol]
13
13
  attribute :after_build_blocks, Array[Proc], default: []
14
+ attribute :skip, Boolean, default: false
14
15
 
15
16
  # The model to be persisted
16
17
  def model
@@ -42,7 +43,7 @@ module CSVImporter
42
43
  set_attribute(model, column_definition, value)
43
44
  end
44
45
 
45
- after_build_blocks.each { |block| block.call(model) }
46
+ after_build_blocks.each { |block| instance_exec(model, &block) }
46
47
 
47
48
  model
48
49
  end
@@ -99,5 +100,9 @@ module CSVImporter
99
100
  def build_model
100
101
  model_klass.new
101
102
  end
103
+
104
+ def skip!
105
+ self.skip = true
106
+ end
102
107
  end
103
108
  end
@@ -52,10 +52,14 @@ module CSVImporter
52
52
  tags << :create
53
53
  end
54
54
 
55
- if row.model.save
56
- tags << :success
55
+ if row.skip?
56
+ tags << :skip
57
57
  else
58
- tags << :failure
58
+ if row.model.save
59
+ tags << :success
60
+ else
61
+ tags << :failure
62
+ end
59
63
  end
60
64
 
61
65
  add_to_report(row, tags)
@@ -74,6 +78,10 @@ module CSVImporter
74
78
  report.updated_rows
75
79
  when [ :update, :failure ]
76
80
  report.failed_to_update_rows
81
+ when [ :create, :skip ]
82
+ report.create_skipped_rows
83
+ when [ :update, :skip ]
84
+ report.update_skipped_rows
77
85
  else
78
86
  raise "Invalid tags #{tags.inspect}"
79
87
  end
@@ -1,3 +1,3 @@
1
1
  module CSVImporter
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv-importer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philippe Creux
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-24 00:00:00.000000000 Z
11
+ date: 2016-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: virtus
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  version: '0'
106
106
  requirements: []
107
107
  rubyforge_project:
108
- rubygems_version: 2.4.5
108
+ rubygems_version: 2.4.5.1
109
109
  signing_key:
110
110
  specification_version: 4
111
111
  summary: CSV Import for humans