csv_model 0.2.1 → 1.0.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +61 -7
- data/lib/csv_model/model.rb +3 -3
- data/lib/csv_model/row.rb +37 -18
- data/lib/csv_model/{object_with_status_snapshot.rb → row_active_record_adaptor.rb} +1 -1
- data/lib/csv_model/version.rb +1 -1
- data/lib/csv_model.rb +2 -2
- data/spec/csv_model/{object_with_status_snapshot_spec.rb → row_active_record_adaptor_spec.rb} +1 -1
- data/spec/csv_model/row_spec.rb +75 -45
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5c7053ec54a07cf27b8e903276c04a728c01511
|
4
|
+
data.tar.gz: fbc25ab237e583a936f6e0e4619c078b966631a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 318238c605891112715aa69677b15f4bcfc6d35c8fcfa3376a1aeccd4e4da2b96059a87df834d167e741b5247998475850c7cfa7caed135b99f976854b5b3130
|
7
|
+
data.tar.gz: 34cddace105c379953649d4a477962d486b2d512558302437189d88335e37490959450fbe7454f5d34b41e41fac944d56bafb561ec21e8f5a83d581b5e9a05fa
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,17 +1,71 @@
|
|
1
|
-
|
1
|
+
CSV Model
|
2
2
|
=========
|
3
3
|
|
4
4
|
[](https://travis-ci.org/Scrimmage/csv_model)
|
5
5
|
|
6
6
|
[](https://codeclimate.com/github/Scrimmage/csv_model)
|
7
7
|
|
8
|
-
|
8
|
+
CSV Model is a bulk import library for ActiveRecord. It parses a CSV into memory, validates the structure, can check for duplicates, and creates or updates the relevant record for each row.
|
9
9
|
|
10
|
-
active_record?
|
11
10
|
|
11
|
+
Requirements
|
12
|
+
------------
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
### Ruby
|
15
|
+
|
16
|
+
CSV Model requires Ruby version **>= 2.0.0**
|
17
|
+
|
18
|
+
|
19
|
+
Installation
|
20
|
+
------------
|
21
|
+
|
22
|
+
CSVModel is distributed as a gem, which is how it should be used in your app.
|
23
|
+
|
24
|
+
Include the gem in your Gemfile:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
gem "csv_model", "~> 1.0"
|
28
|
+
```
|
29
|
+
|
30
|
+
Or, if you want to get the latest, you can get master from the main repository:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
gem "csv_model", :git => "git://github.com/Scrimmage/csv_model.git"
|
34
|
+
```
|
15
35
|
|
16
|
-
|
17
|
-
|
36
|
+
|
37
|
+
Example Usage
|
38
|
+
-----------
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
options = {
|
42
|
+
dry_run: is_dry_run?,
|
43
|
+
legal_columns: structure.legal_columns,
|
44
|
+
primary_key: structure.primary_key_columns,
|
45
|
+
required_columns: structure.required_columns,
|
46
|
+
row_model_finder: model_finder,
|
47
|
+
row_model_mapper: model_mapper,
|
48
|
+
}
|
49
|
+
|
50
|
+
cm = CSVModel::Model.new(data, options)
|
51
|
+
|
52
|
+
if cm.structure_valid?
|
53
|
+
puts "Found structural errors: #{csv.structure_errors.inspect}"
|
54
|
+
else
|
55
|
+
cm.rows.each do |row|
|
56
|
+
status = row.process_row
|
57
|
+
puts "Found row #{row.key} with status #{status} and errors #{row.errors.inspect}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
|
63
|
+
Internal Notes
|
64
|
+
--------------
|
65
|
+
|
66
|
+
Deployment:
|
67
|
+
|
68
|
+
```bash
|
69
|
+
gem build csv_model.gemspec
|
70
|
+
gem push csv_model-x.y.z.gem
|
71
|
+
```
|
data/lib/csv_model/model.rb
CHANGED
@@ -41,8 +41,8 @@ module CSVModel
|
|
41
41
|
header_class.new(row, options)
|
42
42
|
end
|
43
43
|
|
44
|
-
def create_row(row)
|
45
|
-
row = row_class.new(header, row, options)
|
44
|
+
def create_row(row, index)
|
45
|
+
row = row_class.new(header, row, index, options)
|
46
46
|
row.mark_as_duplicate if is_duplicate_key?(row.key)
|
47
47
|
row
|
48
48
|
end
|
@@ -80,7 +80,7 @@ module CSVModel
|
|
80
80
|
# end
|
81
81
|
|
82
82
|
if index > 0
|
83
|
-
@rows << create_row(row)
|
83
|
+
@rows << create_row(row, index)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
rescue CSV::MalformedCSVError => e
|
data/lib/csv_model/row.rb
CHANGED
@@ -4,14 +4,17 @@ module CSVModel
|
|
4
4
|
class Row
|
5
5
|
include Utilities::Options
|
6
6
|
|
7
|
-
attr_reader :data, :header, :marked_as_duplicate
|
7
|
+
attr_reader :data, :header, :model_index, :marked_as_duplicate
|
8
8
|
|
9
|
-
def initialize(header, data, options = {})
|
9
|
+
def initialize(header, data, model_index, options = {})
|
10
10
|
@header = header
|
11
11
|
@data = data
|
12
|
+
@model_index = model_index
|
12
13
|
@options = options
|
13
14
|
end
|
14
15
|
|
16
|
+
alias_method :csv_index, :model_index
|
17
|
+
|
15
18
|
def index(value)
|
16
19
|
index = column_index(value) || value
|
17
20
|
data[index] if index.is_a?(Fixnum) && index >= 0
|
@@ -36,6 +39,14 @@ module CSVModel
|
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
42
|
+
def map_all_attributes(attrs)
|
43
|
+
attrs
|
44
|
+
end
|
45
|
+
|
46
|
+
def map_key_attributes(attrs)
|
47
|
+
attrs
|
48
|
+
end
|
49
|
+
|
39
50
|
def marked_as_duplicate?
|
40
51
|
!!marked_as_duplicate
|
41
52
|
end
|
@@ -44,6 +55,16 @@ module CSVModel
|
|
44
55
|
@marked_as_duplicate = true
|
45
56
|
end
|
46
57
|
|
58
|
+
def process_row
|
59
|
+
return model_instance.status if @processed
|
60
|
+
@processed = true
|
61
|
+
|
62
|
+
model_instance.assign_attributes(all_attributes)
|
63
|
+
model_instance.mark_as_duplicate if marked_as_duplicate?
|
64
|
+
model_instance.save(dry_run: is_dry_run?)
|
65
|
+
model_instance.status
|
66
|
+
end
|
67
|
+
|
47
68
|
def status
|
48
69
|
model_instance.status
|
49
70
|
end
|
@@ -63,7 +84,7 @@ module CSVModel
|
|
63
84
|
private
|
64
85
|
|
65
86
|
def all_attributes
|
66
|
-
@all_attributes ||= column_attributes_with_values(columns)
|
87
|
+
@all_attributes ||= model_mapper.map_all_attributes(column_attributes_with_values(columns))
|
67
88
|
end
|
68
89
|
|
69
90
|
def columns
|
@@ -87,41 +108,39 @@ module CSVModel
|
|
87
108
|
option(:dry_run, false)
|
88
109
|
end
|
89
110
|
|
90
|
-
def
|
91
|
-
|
111
|
+
def model_adaptor
|
112
|
+
CSVModel::RowActiveRecordAdaptor
|
113
|
+
end
|
114
|
+
|
115
|
+
def model_finder
|
116
|
+
option(:row_model_finder)
|
92
117
|
end
|
93
118
|
|
94
119
|
def model_instance
|
95
120
|
@model_instance ||= begin
|
96
121
|
x = inherit_or_delegate(:find_row_model, key_attributes)
|
97
122
|
x ||= inherit_or_delegate(:new_row_model, key_attributes)
|
98
|
-
x =
|
123
|
+
x = model_adaptor.new(x)
|
99
124
|
end
|
100
125
|
end
|
101
126
|
|
127
|
+
def model_mapper
|
128
|
+
option(:row_model_mapper, self)
|
129
|
+
end
|
130
|
+
|
102
131
|
def key_attributes
|
103
132
|
cols = primary_key_columns.any? ? primary_key_columns : columns
|
104
|
-
@key_attributes ||= column_attributes_with_values(cols)
|
133
|
+
@key_attributes ||= model_mapper.map_key_attributes(column_attributes_with_values(cols))
|
105
134
|
end
|
106
135
|
|
107
|
-
|
108
136
|
def primary_key_columns
|
109
137
|
header.primary_key_columns
|
110
138
|
end
|
111
139
|
|
112
|
-
def process_row
|
113
|
-
return if @processed
|
114
|
-
@processed = true
|
115
|
-
|
116
|
-
model_instance.assign_attributes(all_attributes)
|
117
|
-
model_instance.mark_as_duplicate if marked_as_duplicate?
|
118
|
-
model_instance.save(dry_run: is_dry_run?)
|
119
|
-
end
|
120
|
-
|
121
140
|
private
|
122
141
|
|
123
142
|
def inherit_or_delegate(method, *args)
|
124
|
-
try(method, *args) ||
|
143
|
+
try(method, *args) || model_finder.try(method, *args)
|
125
144
|
end
|
126
145
|
|
127
146
|
end
|
data/lib/csv_model/version.rb
CHANGED
data/lib/csv_model.rb
CHANGED
@@ -7,10 +7,10 @@ require 'csv_model/record_status'
|
|
7
7
|
require 'csv_model/utilities'
|
8
8
|
|
9
9
|
require 'csv_model/column'
|
10
|
-
require 'csv_model/row'
|
11
10
|
require 'csv_model/header_row'
|
12
11
|
require 'csv_model/model'
|
13
|
-
require 'csv_model/
|
12
|
+
require 'csv_model/row'
|
13
|
+
require 'csv_model/row_active_record_adaptor'
|
14
14
|
require 'csv_model/version'
|
15
15
|
|
16
16
|
module CSVModel
|
data/spec/csv_model/{object_with_status_snapshot_spec.rb → row_active_record_adaptor_spec.rb}
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe CSVModel::
|
3
|
+
describe CSVModel::RowActiveRecordAdaptor do
|
4
4
|
let(:model) { double("model", changed?: false, marked_for_destruction?: false, new_record?: false, valid?: false) }
|
5
5
|
let(:subject) { described_class.new(model) }
|
6
6
|
|
data/spec/csv_model/row_spec.rb
CHANGED
@@ -5,10 +5,11 @@ describe CSVModel::Row do
|
|
5
5
|
let(:header) { double("header") }
|
6
6
|
let(:column) { double("column", key: "column one", model_attribute: :column_one, name: "Column One") }
|
7
7
|
let(:columns) { [column] }
|
8
|
+
let(:index) { 1 }
|
8
9
|
let(:primary_key_columns) { [] }
|
9
10
|
|
10
11
|
let(:data) { ["Value One"] }
|
11
|
-
let(:subject) { described_class.new(header, data) }
|
12
|
+
let(:subject) { described_class.new(header, data, index) }
|
12
13
|
|
13
14
|
before do
|
14
15
|
allow(header).to receive(:columns).and_return(columns)
|
@@ -17,14 +18,21 @@ describe CSVModel::Row do
|
|
17
18
|
allow(header).to receive(:primary_key_columns).and_return(primary_key_columns)
|
18
19
|
end
|
19
20
|
|
21
|
+
describe "#csv_index, #model_index" do
|
22
|
+
it "returns the index the row was instantiated with" do
|
23
|
+
expect(subject.csv_index).to eq(index)
|
24
|
+
expect(subject.model_index).to eq(index)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
20
28
|
describe "#errors" do
|
21
29
|
context "when no errors" do
|
22
|
-
let(:
|
23
|
-
let(:subject) { described_class.new(header, data,
|
30
|
+
let(:model_finder) { double("model-finder") }
|
31
|
+
let(:subject) { described_class.new(header, data, index, row_model_finder: model_finder) }
|
24
32
|
let(:model_instance) { double("model-instance", changed?: false, marked_for_destruction?: false, new_record?: false, valid?: true) }
|
25
33
|
|
26
34
|
before do
|
27
|
-
allow(
|
35
|
+
allow(model_finder).to receive(:find_row_model).and_return(model_instance)
|
28
36
|
allow(model_instance).to receive(:save)
|
29
37
|
end
|
30
38
|
|
@@ -45,7 +53,7 @@ describe CSVModel::Row do
|
|
45
53
|
end
|
46
54
|
|
47
55
|
context "during a dry-run" do
|
48
|
-
let(:subject) { described_class.new(header, data, dry_run: true) }
|
56
|
+
let(:subject) { described_class.new(header, data, index, dry_run: true) }
|
49
57
|
|
50
58
|
it "returns an error" do
|
51
59
|
expect(subject.errors).to include("Duplicate row")
|
@@ -62,13 +70,13 @@ describe CSVModel::Row do
|
|
62
70
|
end
|
63
71
|
|
64
72
|
context "when the model instance has errors" do
|
65
|
-
let(:
|
66
|
-
let(:subject) { described_class.new(header, data,
|
73
|
+
let(:model_finder) { double("model-finder") }
|
74
|
+
let(:subject) { described_class.new(header, data, index, row_model_finder: model_finder) }
|
67
75
|
let(:model_instance) { double("model-instance", changed?: false, errors: errors, marked_for_destruction?: false, new_record?: false, valid?: false) }
|
68
76
|
let(:errors) { ["Message one", "Message two"] }
|
69
77
|
|
70
78
|
before do
|
71
|
-
allow(
|
79
|
+
allow(model_finder).to receive(:find_row_model).and_return(model_instance)
|
72
80
|
end
|
73
81
|
|
74
82
|
it "includes the model instance errors" do
|
@@ -156,6 +164,30 @@ describe CSVModel::Row do
|
|
156
164
|
end
|
157
165
|
end
|
158
166
|
|
167
|
+
describe "#process_row" do
|
168
|
+
let(:model_finder) { double("model-finder") }
|
169
|
+
let(:model_instance) { double("model-instance", changed?: true, marked_for_destruction?: false, new_record?: false, valid?: true) }
|
170
|
+
let(:subject) { described_class.new(header, data, index, row_model_finder: model_finder) }
|
171
|
+
|
172
|
+
before do
|
173
|
+
allow(model_finder).to receive(:find_row_model).and_return(model_instance)
|
174
|
+
allow(subject).to receive(:all_attributes).and_return(:all_attributes)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "assigns attributes and saves the model instance" do
|
178
|
+
expect(model_instance).to receive(:assign_attributes).with(:all_attributes).ordered
|
179
|
+
expect(model_instance).to receive(:save)
|
180
|
+
subject.process_row
|
181
|
+
end
|
182
|
+
|
183
|
+
it "only processes a record once" do
|
184
|
+
expect(model_instance).to receive(:assign_attributes).with(:all_attributes).ordered
|
185
|
+
expect(model_instance).to receive(:save)
|
186
|
+
subject.process_row
|
187
|
+
subject.process_row
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
159
191
|
describe "#status" do
|
160
192
|
let(:model) { double("model") }
|
161
193
|
let(:wrapper) { double("wrapper", status: :some_status) }
|
@@ -167,7 +199,7 @@ describe CSVModel::Row do
|
|
167
199
|
end
|
168
200
|
|
169
201
|
it "is delegates status to the model" do
|
170
|
-
expect(CSVModel::
|
202
|
+
expect(CSVModel::RowActiveRecordAdaptor).to receive(:new).and_return(wrapper)
|
171
203
|
expect(subject.status).to eq(:some_status)
|
172
204
|
end
|
173
205
|
end
|
@@ -194,6 +226,19 @@ describe CSVModel::Row do
|
|
194
226
|
expect(subject.send(:all_attributes)).to eq(column_one: "Value One")
|
195
227
|
end
|
196
228
|
|
229
|
+
context "with a column mapping" do
|
230
|
+
let(:model_mapper) { double("model-mapper") }
|
231
|
+
let(:subject) { described_class.new(header, data, index, row_model_mapper: model_mapper) }
|
232
|
+
|
233
|
+
before do
|
234
|
+
allow(model_mapper).to receive(:map_all_attributes).with({ column_one: "Value One" }).and_return(mapped_key: "mapped_value")
|
235
|
+
end
|
236
|
+
|
237
|
+
it "maps attributes" do
|
238
|
+
expect(subject.send(:all_attributes)).to eq(mapped_key: "mapped_value")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
197
242
|
context "with multiple columns" do
|
198
243
|
let(:columns) { [
|
199
244
|
double("column", key: "column one", model_attribute: :column_one),
|
@@ -214,8 +259,8 @@ describe CSVModel::Row do
|
|
214
259
|
end
|
215
260
|
|
216
261
|
describe "#inherit_or_delegate" do
|
217
|
-
let(:
|
218
|
-
let(:subject) { described_class.new(header, data,
|
262
|
+
let(:model_finder) { double("model-finder") }
|
263
|
+
let(:subject) { described_class.new(header, data, index, row_model_finder: model_finder) }
|
219
264
|
|
220
265
|
it "doesn't respond to inherit_or_delegate" do
|
221
266
|
expect(subject.respond_to?(:inherit_or_delegate)).to eq(false)
|
@@ -233,7 +278,7 @@ describe CSVModel::Row do
|
|
233
278
|
end
|
234
279
|
|
235
280
|
it "invokes delegate method if delegate exists and internal method is not defined" do
|
236
|
-
expect(
|
281
|
+
expect(model_finder).to receive(:some_method).with(:multiple, :args).and_return(:some_value)
|
237
282
|
expect(subject.send(:inherit_or_delegate, :some_method, :multiple, :args)).to eq(:some_value)
|
238
283
|
end
|
239
284
|
end
|
@@ -275,12 +320,25 @@ describe CSVModel::Row do
|
|
275
320
|
expect(subject.send(:key_attributes)).to eq(column_one: "Value One", column_two: "Value Two")
|
276
321
|
end
|
277
322
|
end
|
323
|
+
|
324
|
+
context "with a column mapping" do
|
325
|
+
let(:model_mapper) { double("model-mapper") }
|
326
|
+
let(:subject) { described_class.new(header, data, index, row_model_mapper: model_mapper) }
|
327
|
+
|
328
|
+
before do
|
329
|
+
allow(model_mapper).to receive(:map_key_attributes).with({ column_one: "Value One" }).and_return(mapped_key: "mapped_value")
|
330
|
+
end
|
331
|
+
|
332
|
+
it "maps attributes" do
|
333
|
+
expect(subject.send(:key_attributes)).to eq(mapped_key: "mapped_value")
|
334
|
+
end
|
335
|
+
end
|
278
336
|
end
|
279
337
|
|
280
338
|
describe "#model_instance" do
|
281
|
-
let(:
|
339
|
+
let(:model_finder) { double("model-finder") }
|
282
340
|
let(:model_instance) { double("model-instance") }
|
283
|
-
let(:subject) { described_class.new(header, data,
|
341
|
+
let(:subject) { described_class.new(header, data, index, row_model_finder: model_finder) }
|
284
342
|
|
285
343
|
before do
|
286
344
|
allow(subject).to receive(:key_attributes).and_return(:key_attributes)
|
@@ -298,7 +356,7 @@ describe CSVModel::Row do
|
|
298
356
|
end
|
299
357
|
|
300
358
|
it "tries to find an instance via model#find_row_model when #find_row_model does not exist" do
|
301
|
-
expect(
|
359
|
+
expect(model_finder).to receive(:find_row_model).with(:key_attributes).and_return(model_instance)
|
302
360
|
expect(subject.send(:model_instance)).to eq(model_instance)
|
303
361
|
end
|
304
362
|
|
@@ -313,39 +371,11 @@ describe CSVModel::Row do
|
|
313
371
|
end
|
314
372
|
|
315
373
|
it "tries to instantiate a new model via model#new_row_model when a model cannot be found and #new_row_model does not exist" do
|
316
|
-
expect(
|
317
|
-
expect(
|
374
|
+
expect(model_finder).to receive(:find_row_model).with(:key_attributes).and_return(nil)
|
375
|
+
expect(model_finder).to receive(:new_row_model).with(:key_attributes).and_return(model_instance)
|
318
376
|
expect(subject.send(:model_instance)).to eq(model_instance)
|
319
377
|
end
|
320
378
|
end
|
321
|
-
|
322
|
-
describe "#process_row" do
|
323
|
-
let(:model) { double("model") }
|
324
|
-
let(:model_instance) { double("model-instance", changed?: true, marked_for_destruction?: false, new_record?: false, valid?: true) }
|
325
|
-
let(:subject) { described_class.new(header, data, model: model) }
|
326
|
-
|
327
|
-
before do
|
328
|
-
allow(model).to receive(:find_row_model).and_return(model_instance)
|
329
|
-
allow(subject).to receive(:all_attributes).and_return(:all_attributes)
|
330
|
-
end
|
331
|
-
|
332
|
-
it "doesn't respond to process_row" do
|
333
|
-
expect(subject.respond_to?(:process_row)).to eq(false)
|
334
|
-
end
|
335
|
-
|
336
|
-
it "assigns attributes and saves the model instance" do
|
337
|
-
expect(model_instance).to receive(:assign_attributes).with(:all_attributes).ordered
|
338
|
-
expect(model_instance).to receive(:save)
|
339
|
-
subject.send(:process_row)
|
340
|
-
end
|
341
|
-
|
342
|
-
it "only processes a record once" do
|
343
|
-
expect(model_instance).to receive(:assign_attributes).with(:all_attributes).ordered
|
344
|
-
expect(model_instance).to receive(:save)
|
345
|
-
subject.send(:process_row)
|
346
|
-
subject.send(:process_row)
|
347
|
-
end
|
348
|
-
end
|
349
379
|
end
|
350
380
|
|
351
381
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Chadwick
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -73,15 +73,15 @@ files:
|
|
73
73
|
- lib/csv_model/extensions.rb
|
74
74
|
- lib/csv_model/header_row.rb
|
75
75
|
- lib/csv_model/model.rb
|
76
|
-
- lib/csv_model/object_with_status_snapshot.rb
|
77
76
|
- lib/csv_model/record_status.rb
|
78
77
|
- lib/csv_model/row.rb
|
78
|
+
- lib/csv_model/row_active_record_adaptor.rb
|
79
79
|
- lib/csv_model/utilities.rb
|
80
80
|
- lib/csv_model/version.rb
|
81
81
|
- spec/csv_model/column_spec.rb
|
82
82
|
- spec/csv_model/header_row_spec.rb
|
83
83
|
- spec/csv_model/model_spec.rb
|
84
|
-
- spec/csv_model/
|
84
|
+
- spec/csv_model/row_active_record_adaptor_spec.rb
|
85
85
|
- spec/csv_model/row_spec.rb
|
86
86
|
- spec/csv_model/utilities_spec.rb
|
87
87
|
- spec/spec_helper.rb
|
@@ -113,7 +113,7 @@ test_files:
|
|
113
113
|
- spec/csv_model/column_spec.rb
|
114
114
|
- spec/csv_model/header_row_spec.rb
|
115
115
|
- spec/csv_model/model_spec.rb
|
116
|
-
- spec/csv_model/
|
116
|
+
- spec/csv_model/row_active_record_adaptor_spec.rb
|
117
117
|
- spec/csv_model/row_spec.rb
|
118
118
|
- spec/csv_model/utilities_spec.rb
|
119
119
|
- spec/spec_helper.rb
|