csv_row_model 0.3.6 → 0.3.7

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: ec97dd8731aef2c4f7ff28c2458e0a2b0a2d2386
4
- data.tar.gz: dae0f044ff3ec2564c074d290fa0027954f88322
3
+ metadata.gz: 733aefc7c7bec4dae6424b679801288c55f5c002
4
+ data.tar.gz: 6875a2d9bb92334abd563cebbfc9302a8566f1df
5
5
  SHA512:
6
- metadata.gz: e1f8b44b5079a08edef1d04b7df4149106a235a8600e93474f83f23961f507ed9945194b51932cd37e968a5215de142a325ebd7e8cdf60cbd715d04c3174b837
7
- data.tar.gz: 9c51f8678d243e14a51ddf90321070f9eb4f7ce1a3386b6e4435f7f793f641e807de3f7b9dc47013edf9b5f7549574d6e82ef9b1a683011af9c1ba17c3b0051f
6
+ metadata.gz: 88d5a04c14243664f3cff35d4c2854f002354d96cc4386dea27243df9d1b0f6567ffd83cc0d32d16754aa9dfb64330d04cf455f328b9f67ae9afc05daf19defa
7
+ data.tar.gz: f87145e2307f338b92e7827fc44422adcceb7b2df4544fdcdf3f9143a20df8472eb9aa6f367b62a9fbec18c6e0e353d3e39a58b27552050c22f6ec1d963317a6
data/README.md CHANGED
@@ -7,7 +7,7 @@ First define your schema:
7
7
  ```ruby
8
8
  class ProjectRowModel
9
9
  include CsvRowModel::Model
10
-
10
+
11
11
  column :id
12
12
  column :name
13
13
  end
@@ -52,7 +52,7 @@ row_model.header # => ["id", "name"]
52
52
 
53
53
  row_model.source_row # => ["1", "Some Project Name"]
54
54
  row_model.mapped_row # => { id: "1", name: "Some Project Name" }, this is `source_row` mapped to `column_names`
55
- row_model.attributes # => { id: "1", name: "Some Project Name" }, this is final attribute values mapped to `column_names`
55
+ row_model.attributes # => { id: "1", name: "Some Project Name" }, this is final attribute values mapped to `column_names`
56
56
 
57
57
  row_model.id # => 1
58
58
  row_model.name # => "Some Project Name"
@@ -441,7 +441,7 @@ class DynamicColumnModel
441
441
  column :first_name
442
442
  column :last_name
443
443
  # header is optional, below is the default_implementation
444
- dynamic_column :skills, header: ->(skill_name) { skill_name }
444
+ dynamic_column :skills, header: ->(skill_name) { skill_name }
445
445
  end
446
446
  ```
447
447
 
@@ -500,4 +500,68 @@ end
500
500
  row_model = CsvRowModel::Import::File.new(file_path, DynamicColumnImportModel).next
501
501
  row_model.attributes # => { first_name: "John", last_name: "Doe", skills: ['No', 'Yes'] }
502
502
  row_model.skills # => ['No', 'Yes']
503
- ```
503
+ ```
504
+
505
+ ## File Model (Mapping)
506
+
507
+ If you have to deal with a mapping on a csv you can use FileModel, isn't complete a this time and many cases isn't covered but can be helpful
508
+
509
+ Here an example of FileRowModel
510
+
511
+ ```ruby
512
+ class FileRowModel
513
+ include CsvRowModel::Model
514
+ include CsvRowModel::Model::FileModel
515
+
516
+ row :string1
517
+ row :string2, header: 'String 2'
518
+
519
+ def self.format_header(column_name, context={})
520
+ ":: - #{column_name} - ::"
521
+ end
522
+ end
523
+ ```
524
+
525
+ You can add `format_header` really helpful in case of I18n
526
+
527
+ you can pass `header:` option but we doesn't use it a the moment.
528
+
529
+ ### Import
530
+
531
+ In import mode we looking for the entries who match with the header, and we get the value in the same row in the right column.
532
+
533
+ i.e [Project Name, My Project]
534
+
535
+ If here `Project Name` is the header so value will be `My Project`
536
+
537
+ ```ruby
538
+ class FileImportModel < FileRowModel
539
+ include CsvRowModel::Import
540
+ include CsvRowModel::Import::FileModel
541
+ end
542
+ ```
543
+
544
+ ### Export
545
+
546
+ In export mode you have to define template, this is more flexible than import. if you put and header, I mean in Symbol into the template, format_header will be call on it, so for I18n replacement is ok, for other cells you can ask the `source_model` or methods in the exporter
547
+
548
+ ```ruby
549
+ class FileExportModel < FileRowModel
550
+ include CsvRowModel::Export
551
+ include CsvRowModel::Export::FileModel
552
+
553
+ def rows_template
554
+ @rows_template ||= begin
555
+ [
556
+ [ :string1, '' , string_value(1) ],
557
+ [ 'String 2', '', '' , '' ],
558
+ [ '' , '', '' , string_value(2) ],
559
+ ]
560
+ end
561
+ end
562
+
563
+ def string_value(number)
564
+ source_model.string_value(number)
565
+ end
566
+ end
567
+ ```
@@ -7,17 +7,15 @@ module CsvRowModel
7
7
  # and everything else is return as is.
8
8
  def to_rows
9
9
  rows_template.map do |row|
10
- result = []
11
- row.each do |cell|
12
- if self.class.is_row_name? cell
13
- header_matchs = self.class.options(cell)[:header_matchs]
14
- result << "#{header_matchs ? header_matchs.first : self.class.format_header(cell, context)}"
15
- result << "#{attributes[cell]}"
16
- else
17
- result << cell.to_s
10
+ [].tap do |result|
11
+ row.each do |cell|
12
+ if header? cell
13
+ result << self.class.format_header(cell, context)
14
+ else
15
+ result << cell.to_s
16
+ end
18
17
  end
19
18
  end
20
- result
21
19
  end
22
20
  end
23
21
 
@@ -33,6 +31,13 @@ module CsvRowModel
33
31
  class_methods do
34
32
  def setup(csv, context, with_headers: true); end
35
33
  end
34
+
35
+ private
36
+
37
+ def header?(cell)
38
+ self.class.is_row_name? cell
39
+ end
40
+
36
41
  end
37
42
  end
38
43
  end
@@ -11,33 +11,37 @@ module CsvRowModel
11
11
  #
12
12
  # @param cell [String] the cell's string
13
13
  # @return [Integer] returns index of the header_match that cell match
14
- def index_header_match(cell)
15
- match = header_matchers.each_with_index.select do |matcher, index|
14
+ def index_header_match(cell, context)
15
+ match = header_matchers(context).each_with_index.select do |matcher, index|
16
16
  cell.match(matcher)
17
17
  end.first
18
+
18
19
  match ? match[1] : nil
19
20
  end
20
21
 
21
22
  # @return [Array] header_matchs matchers for the row model
22
- def header_matchers
23
+ def header_matchers(context)
23
24
  @header_matchers ||= begin
24
25
  columns.map do |name, options|
25
- matchers = options[:header_matchs] || [name.to_s]
26
- Regexp.new(matchers.join('|'),Regexp::IGNORECASE)
27
- end
26
+ if formatted_header = self.format_header(name, context)
27
+ Regexp.new("^#{formatted_header}$", Regexp::IGNORECASE)
28
+ end
29
+ end.compact
28
30
  end
29
31
  end
30
32
 
31
33
  def next(csv, source_header, context={}, previous=nil)
32
34
  return csv.read_row unless csv.next_row
33
35
 
34
- source_row = Array.new(header_matchers.size)
36
+ source_row = Array.new(header_matchers(context).size)
35
37
 
36
38
  while csv.next_row
37
39
  current_row = csv.read_row
40
+
38
41
  current_row.each_with_index do |cell, position|
42
+ next if position == 0 # This is a hack to ignore the first column because of infos.csv have 'Compte' twice...
39
43
  next if cell.blank?
40
- index = index_header_match(cell)
44
+ index = index_header_match(cell, context)
41
45
  next unless index
42
46
  source_row[index] = current_row[position + 1]
43
47
  break
@@ -50,5 +54,3 @@ module CsvRowModel
50
54
  end
51
55
  end
52
56
  end
53
-
54
-
@@ -1,3 +1,3 @@
1
1
  module CsvRowModel
2
- VERSION = "0.3.6"
2
+ VERSION = "0.3.7"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv_row_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Chung
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-01-06 00:00:00.000000000 Z
12
+ date: 2016-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel