csv_row_model 0.3.6 → 0.3.7
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 +4 -4
- data/README.md +68 -4
- data/lib/csv_row_model/export/file_model.rb +14 -9
- data/lib/csv_row_model/import/file_model.rb +12 -10
- data/lib/csv_row_model/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 733aefc7c7bec4dae6424b679801288c55f5c002
|
4
|
+
data.tar.gz: 6875a2d9bb92334abd563cebbfc9302a8566f1df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
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.
|
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-
|
12
|
+
date: 2016-01-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|