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 +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
|