rails_spreadsheet_reader 0.1.4 → 0.2.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 +8 -8
- data/lib/generators/rails/spreadsheet_generator.rb +8 -3
- data/lib/generators/rails/templates/spreadsheet.rb +23 -52
- data/lib/rails_spreadsheet_reader/base.rb +83 -91
- data/lib/rails_spreadsheet_reader/row_collection.rb +15 -16
- data/lib/rails_spreadsheet_reader/version.rb +1 -1
- data/rails_spreadsheet_reader.gemspec +2 -0
- data/spec/base_spec.rb +83 -32
- data/spec/db/database.rb +74 -0
- data/spec/files/employee_enterprise.csv +8 -0
- data/spec/files/student_benefit.csv +10 -0
- data/spec/files/student_benefit_invalid.csv +3 -0
- data/spec/lib/generators/generator_spec.rb +28 -0
- data/spec/row_collection_spec.rb +14 -25
- data/spec/spec_helper.rb +4 -0
- data/spec/spreadsheets/custom_persist_spreadsheet.rb +27 -0
- data/spec/spreadsheets/employee_enterprise_spreadsheet.rb +22 -0
- data/spec/{models → spreadsheets}/empty_column_spreadsheet.rb +0 -0
- data/spec/{models → spreadsheets}/invalid_column_spreadsheet.rb +1 -1
- data/spec/spreadsheets/student_benefit_spreadsheet.rb +23 -0
- data/spec/spreadsheets/user_invalid_spreadsheet.rb +23 -0
- data/spec/{models → spreadsheets}/user_spreadsheet.rb +7 -3
- data/spec/user_spec.rb +22 -0
- metadata +56 -10
- data/spec/models/user_invalid_spreadsheet.rb +0 -24
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NGQ3ZmFlMDQxYjBjNDExOGEwZGZiMmQ2YjkxNmQ4ZGM5ZmQ3ZWUwZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDlhNjBkZDZkYThkYjg0ZmE2ZmY4ZDQ5MjZjYjc0ZjJhMGE2ZGY4OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YmQ1YjRmNWM2NTdmMWQxZGI0NmRmYmRhMWFmMThkNzdmOGM0M2MwMDkyZDY4
|
10
|
+
ZjVkMzMxZTAyMWNkZjM0NjY5NzY3ZDQwYzJjZjdmYmU2OTIzMzMyOTcyMTc1
|
11
|
+
NmVjZWU1YzVlOTM1NzdhODk3NTFiNGVhZThhOTUzY2RjNjk5Nzc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjEwNzYxZDE4MzQ5OWZmYTM3MzNkMjEyYmVlZGEzNzRlOTU2MjMyZjBjYzlh
|
14
|
+
MzkwODMxMGY4OWVmM2ZkZjI0ZWVkZTAyZDUxN2Y1YzVmZGJiZWI3ODNiNmE5
|
15
|
+
NTEyYjRjMTE4YWM0NzMzYTM0OWNmMWEzZGM1ZmQ2NzI5ZDRhYzI=
|
@@ -7,13 +7,18 @@ module Rails
|
|
7
7
|
|
8
8
|
source_root File.expand_path('../templates', __FILE__)
|
9
9
|
argument :name, :type => :string
|
10
|
+
class_option :models, type: :array, aliases: '-m', default: ['Model1', 'Model2']
|
11
|
+
class_option :simple, default: false
|
12
|
+
class_option :attributes, aliases: '-a', default: ['attr1', 'attr2']
|
10
13
|
|
11
14
|
def generate_spreadsheet
|
15
|
+
puts 'hola'
|
12
16
|
file_prefix = set_filename(name)
|
13
17
|
@spreadsheet_name = set_spreadsheet_name(name)
|
14
|
-
|
15
|
-
|
16
|
-
|
18
|
+
@models = @options[:models]
|
19
|
+
@simple = @options[:simple]
|
20
|
+
@attributes = @options[:attributes]
|
21
|
+
template 'spreadsheet.rb', "app/spreadsheet_reader/#{file_prefix}_spreadsheet.rb"
|
17
22
|
end
|
18
23
|
|
19
24
|
private
|
@@ -1,68 +1,39 @@
|
|
1
1
|
class <%= @spreadsheet_name %>Spreadsheet < RailsSpreadsheetReader::Base
|
2
2
|
|
3
|
-
#
|
4
|
-
# attr_accessor
|
3
|
+
# Add alias names for excel columns
|
4
|
+
# attr_accessor <%= @attributes.map{|a| ":#{a}"}.join(', ') %>
|
5
5
|
|
6
|
-
#
|
6
|
+
# Add validation for your fields
|
7
7
|
# validates_presence_of :attr1
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# or
|
12
|
-
|
13
|
-
|
14
|
-
# return { attr1: 0, attr2: 1, ... }
|
9
|
+
# Map attributes to your spreadsheet columns (0-based).
|
10
|
+
# You can use a hash { attr1: 0, attr2: 1, attr3: 2, ... }
|
11
|
+
# or an array %w(attr1 attr2 attr3 ...) (which maps each key to their index).
|
12
|
+
def self.headers
|
13
|
+
{<%= @attributes.map.with_index{|a,i| "#{a}: #{i}"}.join(', ') %>}
|
15
14
|
end
|
16
15
|
|
17
|
-
#
|
16
|
+
# Set the row number where the data start, default is 2 (1-based)
|
18
17
|
def self.starting_row
|
19
18
|
2
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# the set of rows of the excel. For example, you can check here if a
|
26
|
-
# excel column is unique. It have to raise an exception if there was
|
27
|
-
# an error with a certain row.
|
28
|
-
#
|
29
|
-
# Example:
|
30
|
-
#
|
31
|
-
# def self.validate_multiple_rows(row_collection)
|
32
|
-
# username_list = []
|
33
|
-
# row_collection.rows.each do |row|
|
34
|
-
# if username_list.include?(row.username)
|
35
|
-
# row_collection.invalid_row = row
|
36
|
-
# row.errors[:username] = 'is unique'
|
37
|
-
# raise 'Validation Error'
|
38
|
-
# else
|
39
|
-
# username_list << row.username
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
# end
|
43
|
-
#
|
21
|
+
# Returns 1 or more ActiveRecord classes where data will be saved
|
22
|
+
def self.models
|
23
|
+
<%= @models.count == 1 ? @models.first : @models.join(', ') %>
|
44
24
|
end
|
45
25
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#
|
50
|
-
# row, you have to Rollback the valid transactions, set the
|
51
|
-
# invalid error to the row_collection and set the row errors to the
|
52
|
-
# row object.
|
53
|
-
#
|
54
|
-
# Example:
|
55
|
-
# def self.persist(row_collection)
|
56
|
-
# User.transaction do
|
57
|
-
# row_collection.rows.each do |row|
|
58
|
-
# user = User.new(attr1: row.attr1, attr2: row.attr2, ...)
|
59
|
-
# unless user.save
|
60
|
-
# row_collection.set_invalid_row(row, user) # pass the model with errors as second parameter
|
61
|
-
# rollback # use the rollback helper to rollback the transaction.
|
62
|
-
# end
|
63
|
-
# end
|
64
|
-
# end
|
65
|
-
# end
|
26
|
+
# Map a spreadsheet instance to model parameters
|
27
|
+
<% @models.each do |model| %>
|
28
|
+
def <%= model.downcase %>
|
29
|
+
# Returns { attr1: self.attr1, attr2: self.attr2 }
|
66
30
|
end
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
# Persist
|
34
|
+
#def persist
|
35
|
+
# Create or save your record. By default, it will use your methods
|
36
|
+
# defined above (<%= @models.map{|m| m.downcase}.join(', ') %>)
|
37
|
+
#end
|
67
38
|
|
68
39
|
end
|
@@ -7,32 +7,54 @@ module RailsSpreadsheetReader
|
|
7
7
|
class Base
|
8
8
|
|
9
9
|
include ActiveModel::Model
|
10
|
+
include ActiveModel::Validations::Callbacks
|
10
11
|
|
11
12
|
class MethodNotImplementedError < StandardError; end
|
12
13
|
class InvalidTypeError < StandardError; end
|
13
14
|
|
14
15
|
attr_accessor :row_number
|
16
|
+
attr_accessor :record_with_error
|
17
|
+
attr_accessor :copied_errors
|
18
|
+
attr_accessor :collection
|
15
19
|
|
16
|
-
|
20
|
+
BASE_ATTRIBUTES = %w(row_number record_with_error copied_errors collection)
|
17
21
|
|
18
|
-
|
19
|
-
# method flushes errors.
|
20
|
-
validate :copy_errors_on_validation
|
22
|
+
validate :check_record_with_error
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
errors.add(:base, msg)
|
24
|
+
def check_record_with_error
|
25
|
+
if record_with_error.present? and record_with_error.errors.any?
|
26
|
+
record_with_error.errors.full_messages.each do |msg|
|
27
|
+
@errors.add(:base, msg)
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def self.last_record
|
33
|
+
@last_record ||= nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.last_record=(record)
|
37
|
+
@last_record = record
|
38
|
+
end
|
39
|
+
|
40
|
+
def models
|
41
|
+
fail(
|
42
|
+
MethodNotImplementedError,
|
43
|
+
'Please implement this method in your class.'
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def persist
|
48
|
+
models = self.class.models.is_a?(Array) ? self.class.models : [self.class.models]
|
49
|
+
models.each do |model|
|
50
|
+
method_name = model.model_name.human.downcase
|
51
|
+
if respond_to?(method_name)
|
52
|
+
instance = model.new(send(model.model_name.human.downcase))
|
53
|
+
else
|
54
|
+
instance = model.new(as_json(except: BASE_ATTRIBUTES))
|
55
|
+
end
|
56
|
+
instance.save!
|
57
|
+
end
|
36
58
|
end
|
37
59
|
|
38
60
|
# Defines the starting row of the excel where the class should start reading the data.
|
@@ -48,19 +70,19 @@ module RailsSpreadsheetReader
|
|
48
70
|
# a Array of strings/symbols (representing columns names) or a Hash (which map column names to columns indexes).
|
49
71
|
#
|
50
72
|
# Array Example
|
51
|
-
# def self.
|
73
|
+
# def self.headers
|
52
74
|
# [:username, :email, :gender]
|
53
75
|
# end
|
54
76
|
#
|
55
77
|
# Hash Example
|
56
|
-
# def self.
|
78
|
+
# def self.headers
|
57
79
|
# { :username => 0, :email => 1, :gender => 2 }
|
58
80
|
# end
|
59
81
|
#
|
60
82
|
# == Returns:
|
61
83
|
# An Array or a Hash defining the columns of the excel.
|
62
84
|
#
|
63
|
-
def self.
|
85
|
+
def self.headers
|
64
86
|
fail(
|
65
87
|
MethodNotImplementedError,
|
66
88
|
'Please implement this method in your class.'
|
@@ -73,11 +95,11 @@ module RailsSpreadsheetReader
|
|
73
95
|
# order of the columns.
|
74
96
|
#
|
75
97
|
# For example, given the following self.columns definition
|
76
|
-
# def self.
|
98
|
+
# def self.headers
|
77
99
|
# [:username, :email, :gender]
|
78
100
|
# end
|
79
101
|
# Or
|
80
|
-
# def self.
|
102
|
+
# def self.headers
|
81
103
|
# { :username => 0, :email => 1, :gender => 2 }
|
82
104
|
# end
|
83
105
|
# Row.formatted([username email@test.cl male]) will return
|
@@ -111,6 +133,7 @@ module RailsSpreadsheetReader
|
|
111
133
|
# Array or Hash of values which represents an excel column.
|
112
134
|
|
113
135
|
def initialize(arr_or_hash = {})
|
136
|
+
self.copied_errors = ActiveModel::Errors.new(self)
|
114
137
|
if arr_or_hash.is_a?(Array)
|
115
138
|
super(self.class.formatted_hash(arr_or_hash))
|
116
139
|
else
|
@@ -118,66 +141,39 @@ module RailsSpreadsheetReader
|
|
118
141
|
end
|
119
142
|
end
|
120
143
|
|
121
|
-
#
|
122
|
-
# idea of this method is to run validations that have to do with
|
123
|
-
# the set of rows of the excel. For example, you can check here if a
|
124
|
-
# excel column is unique:
|
125
|
-
#
|
126
|
-
# Example:
|
127
|
-
#
|
128
|
-
# def self.validate_multiple_rows(row_collection)
|
129
|
-
# username_list = []
|
130
|
-
# row_collection.each do |row|
|
131
|
-
# if username_list.include?(row.username)
|
132
|
-
# row_collection.invalid_row = row
|
133
|
-
# row.errors[:username] = 'is unique'
|
134
|
-
# else
|
135
|
-
# username_list << row.username
|
136
|
-
# end
|
137
|
-
# end
|
138
|
-
# end
|
139
|
-
#
|
140
|
-
# == Parameters:
|
141
|
-
# row_collection::
|
142
|
-
# SpreadsheetReader::RowCollection instance
|
143
|
-
def self.validate_multiple_rows(row_collection)
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
# This method is called after the self.validate_multiple_rows method
|
148
|
-
# only if it have not raised an exception. The idea of this method
|
149
|
-
# is to persist the row's data. If there was an error with a certain
|
150
|
-
# row, you have to Rollback the valid transactions, set the
|
151
|
-
# invalid error to the row_collection and set the row errors to the
|
152
|
-
# row object.
|
153
|
-
#
|
154
|
-
# Example:
|
155
|
-
# def self.persist(row_collection)
|
156
|
-
# User.transaction do
|
157
|
-
# row_collection.each do |row|
|
158
|
-
# user = User.new(attr1: row.attr1, attr2: row.attr2, ...)
|
159
|
-
# unless user.save
|
160
|
-
# row_collection.set_invalid_row(row, user) # pass the model with errors as second parameter
|
161
|
-
# rollback # use the rollback helper to rollback the transaction.
|
162
|
-
# end
|
163
|
-
# end
|
164
|
-
# end
|
165
|
-
# end
|
144
|
+
# Persist all rows of collection if they all are valid
|
166
145
|
#
|
167
146
|
# == Parameters:
|
168
147
|
# row_collection::
|
169
148
|
# SpreadsheetReader::RowCollection instance
|
170
|
-
def self.persist(
|
171
|
-
|
149
|
+
def self.persist(collection)
|
150
|
+
if collection.valid?
|
151
|
+
ActiveRecord::Base.transaction do
|
152
|
+
collection.each do |row|
|
153
|
+
# If any of validations fail ActiveRecord::RecordInvalid gets raised.
|
154
|
+
# If any of the before_* callbacks return false the action is cancelled and save! raises ActiveRecord::RecordNotSaved.
|
155
|
+
begin
|
156
|
+
row.persist
|
157
|
+
rescue ActiveRecord::RecordInvalid => e
|
158
|
+
row.record_with_error = e.record
|
159
|
+
collection.invalid_row = row
|
160
|
+
rollback
|
161
|
+
rescue ActiveRecord::RecordNotSaved => e
|
162
|
+
row.model_with_error = e.record
|
163
|
+
collection.invalid_row = row
|
164
|
+
rollback
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
172
169
|
end
|
173
170
|
|
174
|
-
def self.
|
171
|
+
def self.open(spreadsheet_file)
|
175
172
|
Roo::Spreadsheet.open(spreadsheet_file)
|
176
173
|
end
|
177
174
|
|
178
|
-
# Read and validates the given #spreadsheet_file.
|
179
|
-
#
|
180
|
-
# Then calls #validate_multiple_rows and finally ends with #persist
|
175
|
+
# Read and validates the given #spreadsheet_file. Persistence is triggered
|
176
|
+
# after all validation pass
|
181
177
|
#
|
182
178
|
# == Parameters:
|
183
179
|
# spreadsheet_file::
|
@@ -185,20 +181,27 @@ module RailsSpreadsheetReader
|
|
185
181
|
# == Returns:
|
186
182
|
# row_collection::
|
187
183
|
# SpreadsheetReader::RowCollection instance
|
188
|
-
def self.
|
184
|
+
def self.read(spreadsheet_file)
|
189
185
|
|
190
|
-
if
|
186
|
+
if headers.empty?
|
191
187
|
raise MethodNotImplementedError
|
192
188
|
end
|
193
189
|
|
194
|
-
spreadsheet =
|
195
|
-
|
190
|
+
spreadsheet = open(spreadsheet_file)
|
191
|
+
collection = RailsSpreadsheetReader::RowCollection.new
|
192
|
+
|
193
|
+
# Populate collection
|
194
|
+
(starting_row..spreadsheet.last_row).each do |row_number|
|
195
|
+
parameters = formatted_hash(spreadsheet.row(row_number))
|
196
|
+
parameters[:row_number] = row_number
|
197
|
+
parameters[:collection] = collection
|
198
|
+
collection << self.new(parameters)
|
199
|
+
end
|
196
200
|
|
197
|
-
|
198
|
-
|
199
|
-
persist(row_collection) if row_collection.valid?
|
200
|
-
row_collection
|
201
|
+
# Validation and persist
|
202
|
+
persist(collection)
|
201
203
|
|
204
|
+
collection
|
202
205
|
end
|
203
206
|
|
204
207
|
# Transform an array [a0, a1, a2, ...] to a Hash { a0 => 0, a1 => 1, etc }
|
@@ -209,22 +212,11 @@ module RailsSpreadsheetReader
|
|
209
212
|
|
210
213
|
private
|
211
214
|
|
212
|
-
# Calls row.valid? on every row of the spreadsheet.
|
213
|
-
# Stops when a row is an invalid ActiveModel::Model.
|
214
|
-
def self.validate_rows(spreadsheet, row_collection)
|
215
|
-
(starting_row..spreadsheet.last_row).each do |number|
|
216
|
-
hash = formatted_hash(spreadsheet.row(number))
|
217
|
-
hash[:row_number] = number
|
218
|
-
row_collection.push self.new(hash)
|
219
|
-
break if row_collection.invalid?
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
215
|
# Returns the Hash representation of the defined columns
|
224
216
|
def self.format
|
225
217
|
|
226
|
-
if
|
227
|
-
return
|
218
|
+
if headers.is_a?(Array) or headers.is_a?(Hash)
|
219
|
+
return headers.is_a?(Array) ? array_to_hash(headers) : headers
|
228
220
|
end
|
229
221
|
|
230
222
|
fail(
|
@@ -8,20 +8,20 @@ module RailsSpreadsheetReader
|
|
8
8
|
self.rows = []
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
self.invalid_row = row if row.invalid?
|
11
|
+
def <<(row)
|
13
12
|
self.rows << row
|
14
13
|
end
|
15
14
|
|
16
|
-
def invalid_row=(row)
|
17
|
-
if row.invalid?
|
18
|
-
@invalid_row = row
|
19
|
-
end
|
20
|
-
# TODO: Throw exception maybe?
|
21
|
-
end
|
22
|
-
|
23
15
|
def valid?
|
24
|
-
|
16
|
+
valid = true
|
17
|
+
rows.each do |row|
|
18
|
+
if row.invalid?
|
19
|
+
self.invalid_row = row
|
20
|
+
valid = false
|
21
|
+
break
|
22
|
+
end
|
23
|
+
end
|
24
|
+
valid
|
25
25
|
end
|
26
26
|
|
27
27
|
def invalid?
|
@@ -29,18 +29,17 @@ module RailsSpreadsheetReader
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def errors
|
32
|
-
self.invalid_row.errors
|
33
|
-
end
|
34
|
-
|
35
|
-
def set_invalid_row(row, model_with_errors)
|
36
|
-
row.copy_errors(model_with_errors)
|
37
|
-
self.invalid_row = row
|
32
|
+
invalid? ? self.invalid_row.errors : []
|
38
33
|
end
|
39
34
|
|
40
35
|
def each(&block)
|
41
36
|
self.rows.each(&block)
|
42
37
|
end
|
43
38
|
|
39
|
+
def count
|
40
|
+
self.rows.count
|
41
|
+
end
|
42
|
+
|
44
43
|
end
|
45
44
|
|
46
45
|
end
|
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
24
24
|
spec.add_development_dependency 'factory_girl', '~> 4.4'
|
25
|
+
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
26
|
+
spec.add_development_dependency 'generator_spec', '~> 0.9'
|
25
27
|
|
26
28
|
spec.add_dependency 'roo', '~> 1.13'
|
27
29
|
spec.add_dependency 'rails', '~> 4.2.0'
|
data/spec/base_spec.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
require_relative 'models/invalid_column_spreadsheet'
|
3
|
-
require_relative 'models/user_spreadsheet'
|
4
|
-
require_relative 'models/user_invalid_spreadsheet'
|
5
|
-
require_relative 'models/empty_column_spreadsheet.rb'
|
1
|
+
require_relative 'spec_helper'
|
6
2
|
|
7
3
|
def test_file(filename, ext)
|
8
4
|
File.open(File.join TEST_DIR, "#{filename}.#{ext}")
|
@@ -11,7 +7,7 @@ end
|
|
11
7
|
describe RailsSpreadsheetReader::Base do
|
12
8
|
|
13
9
|
it 'not implementing columns method should raise an error' do
|
14
|
-
expect { RailsSpreadsheetReader::Base.
|
10
|
+
expect { RailsSpreadsheetReader::Base.headers }.to raise_error(RailsSpreadsheetReader::Base::MethodNotImplementedError)
|
15
11
|
end
|
16
12
|
|
17
13
|
it 'format method should raise an error if columns method is not valid' do
|
@@ -28,16 +24,16 @@ describe RailsSpreadsheetReader::Base do
|
|
28
24
|
|
29
25
|
it 'Base.open_spreadsheet should return a Roo::Base instance' do
|
30
26
|
file = test_file 'users', :csv
|
31
|
-
roo_row = RailsSpreadsheetReader::Base.
|
27
|
+
roo_row = RailsSpreadsheetReader::Base.open file
|
32
28
|
expect(roo_row.is_a?(Roo::Base)).not_to eq(false)
|
33
29
|
end
|
34
30
|
|
35
|
-
it 'empty
|
31
|
+
it 'empty headers should raise an error' do
|
36
32
|
file = test_file 'users', :csv
|
37
|
-
expect { EmptyColumnSpreadsheet.
|
33
|
+
expect { EmptyColumnSpreadsheet.read(file) }.to raise_error(RailsSpreadsheetReader::Base::MethodNotImplementedError)
|
38
34
|
end
|
39
35
|
|
40
|
-
it '#formatted_hash should work in a derived class which overrides "
|
36
|
+
it '#formatted_hash should work in a derived class which overrides "headers" method' do
|
41
37
|
formatted_hash = UserSpreadsheet.formatted_hash %w(username email@test.com male)
|
42
38
|
expect(formatted_hash).to eq({ username: 'username', email: 'email@test.com', gender: 'male' })
|
43
39
|
|
@@ -46,41 +42,96 @@ describe RailsSpreadsheetReader::Base do
|
|
46
42
|
end
|
47
43
|
|
48
44
|
it '#new from derived class' do
|
49
|
-
|
50
|
-
expect(
|
51
|
-
expect(
|
52
|
-
expect(
|
53
|
-
|
54
|
-
|
55
|
-
expect(
|
56
|
-
expect(
|
57
|
-
expect(
|
45
|
+
row = UserSpreadsheet.new(%w(username email@test.com male))
|
46
|
+
expect(row.username).to eq('username')
|
47
|
+
expect(row.email).to eq('email@test.com')
|
48
|
+
expect(row.gender).to eq('male')
|
49
|
+
|
50
|
+
row = UserSpreadsheet.new({ email: 'email@test.com', gender: 'male', username: 'username' })
|
51
|
+
expect(row.username).to eq('username')
|
52
|
+
expect(row.email).to eq('email@test.com')
|
53
|
+
expect(row.gender).to eq('male')
|
58
54
|
end
|
59
55
|
|
60
56
|
it '#valid? should work as desired (derived class)' do
|
61
|
-
|
62
|
-
expect(
|
57
|
+
valid_row = UserSpreadsheet.new({ email: 'email@test.com', gender: 'male', username: 'username' })
|
58
|
+
expect(valid_row.valid?).to eq(true)
|
63
59
|
|
64
|
-
|
65
|
-
expect(
|
60
|
+
invalid_row = UserSpreadsheet.new({ gender: 'male', username: 'username' })
|
61
|
+
expect(invalid_row.valid?).to eq(false)
|
66
62
|
end
|
67
63
|
|
68
64
|
it '#read_spreadsheet should be invalid because a row is not valid' do
|
69
65
|
file = test_file 'users_invalid', :csv
|
70
|
-
row_collection = UserSpreadsheet.
|
66
|
+
row_collection = UserSpreadsheet.read(file)
|
71
67
|
expect(row_collection.valid?).to eq(false)
|
72
68
|
expect(row_collection.invalid_row.row_number).to eq(2)
|
73
69
|
expect(row_collection.errors.full_messages).to eq(["Email can't be blank"])
|
74
70
|
end
|
75
71
|
|
76
|
-
it '
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
expect(
|
81
|
-
|
82
|
-
|
83
|
-
|
72
|
+
it 'A row with an invalid record should be invalid' do
|
73
|
+
row = UserSpreadsheet.new
|
74
|
+
invalid_record = User.make_invalid
|
75
|
+
row.record_with_error = invalid_record
|
76
|
+
expect(row.valid?).to eq(false)
|
77
|
+
expect(row.invalid?).to eq(true)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'A row should persist a valid record' do
|
81
|
+
params = User.make_valid.as_json
|
82
|
+
params.delete('id')
|
83
|
+
expect(User.exists?(params)).to eq(false)
|
84
|
+
row = UserSpreadsheet.new(params)
|
85
|
+
row.persist
|
86
|
+
expect(User.exists?(params)).to eq(true)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'A row should fail when persisting an invalid record' do
|
90
|
+
params = User.make_invalid.as_json
|
91
|
+
params.delete('id')
|
92
|
+
UserSpreadsheet.headers
|
93
|
+
UserSpreadsheet.models
|
94
|
+
row = UserSpreadsheet.new(params)
|
95
|
+
expect { row.persist }.to raise_error(ActiveRecord::RecordInvalid)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'Should not save records to database when failing' do
|
99
|
+
file = test_file 'student_benefit_invalid', :csv
|
100
|
+
student_count = Student.count
|
101
|
+
benefit_count = Benefit.count
|
102
|
+
result = StudentBenefitSpreadsheet.read(file)
|
103
|
+
expect(result.valid?).to eq(false)
|
104
|
+
expect(student_count).to eq(Student.count)
|
105
|
+
expect(benefit_count).to eq(Benefit.count)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'Should save multiple records to database' do
|
109
|
+
file = test_file 'student_benefit', :csv
|
110
|
+
student_count = Student.count
|
111
|
+
benefit_count = Benefit.count
|
112
|
+
result = StudentBenefitSpreadsheet.read(file)
|
113
|
+
expect(result.valid?).to eq(true)
|
114
|
+
expect(student_count).to eq(Student.count - result.count)
|
115
|
+
expect(benefit_count).to eq(Benefit.count - result.count)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'Spreadsheet.models order does matter when persisting' do
|
119
|
+
file = test_file 'employee_enterprise', :csv
|
120
|
+
result = EmployeeEnterpriseSpreadsheet.read(file)
|
121
|
+
expect(result.valid?).to eq(true)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'Spreadsheet with custom persist works as expected' do
|
125
|
+
file = test_file 'employee_enterprise', :csv
|
126
|
+
result = CustomPersistSpreadsheet.read(file)
|
127
|
+
expect(result.valid?).to eq(true)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'Custom validator using uniqueness inside the same excel' do
|
131
|
+
file = test_file 'users_invalid', :csv
|
132
|
+
result = UserInvalidSpreadsheet.read(file)
|
133
|
+
expect(result.valid?).to eq(false)
|
134
|
+
expect(result.invalid_row.errors[:username]).to eq(["Username already defined in excel at row 4"])
|
84
135
|
end
|
85
136
|
|
86
137
|
end
|
data/spec/db/database.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
# Connect to an in-memory sqlite3 database
|
5
|
+
ActiveRecord::Base.establish_connection(
|
6
|
+
adapter: 'sqlite3',
|
7
|
+
database: ':memory:'
|
8
|
+
)
|
9
|
+
|
10
|
+
# Drop tables
|
11
|
+
connection = ActiveRecord::Base.connection
|
12
|
+
connection.tables.each do |table|
|
13
|
+
connection.drop_table(table)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Define a minimal database schema
|
17
|
+
ActiveRecord::Schema.define do
|
18
|
+
create_table :users, force: true do |t|
|
19
|
+
t.string :email
|
20
|
+
t.string :username
|
21
|
+
t.string :name
|
22
|
+
t.string :gender
|
23
|
+
end
|
24
|
+
create_table :students, force: true do |t|
|
25
|
+
t.string :code
|
26
|
+
t.string :name
|
27
|
+
end
|
28
|
+
create_table :benefits, force: true do |t|
|
29
|
+
t.string :code
|
30
|
+
t.string :name
|
31
|
+
end
|
32
|
+
create_table :employees, force: true do |t|
|
33
|
+
t.string :name
|
34
|
+
t.references :enterprise
|
35
|
+
end
|
36
|
+
create_table :enterprises, force: true do |t|
|
37
|
+
t.string :name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Define the models
|
42
|
+
class User < ActiveRecord::Base
|
43
|
+
validates_presence_of :email, :username
|
44
|
+
validates_uniqueness_of :username, :email
|
45
|
+
|
46
|
+
def self.make_valid
|
47
|
+
User.new(username: 'username', email: 'username@example.com')
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.make_invalid
|
51
|
+
User.new(username: 'username')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class Student < ActiveRecord::Base
|
57
|
+
validates_uniqueness_of :code
|
58
|
+
validates_presence_of :code
|
59
|
+
end
|
60
|
+
|
61
|
+
class Benefit < ActiveRecord::Base
|
62
|
+
validates_uniqueness_of :code
|
63
|
+
validates_presence_of :code
|
64
|
+
end
|
65
|
+
|
66
|
+
class Employee < ActiveRecord::Base
|
67
|
+
belongs_to :enterprise
|
68
|
+
end
|
69
|
+
|
70
|
+
class Enterprise < ActiveRecord::Base
|
71
|
+
has_many :employees
|
72
|
+
validates_presence_of :name
|
73
|
+
validates_uniqueness_of :name
|
74
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# spec/lib/generators/test/test_generator_spec.rb
|
2
|
+
|
3
|
+
require "generator_spec"
|
4
|
+
require_relative '../../../lib/generators/rails/spreadsheet_generator'
|
5
|
+
|
6
|
+
describe Rails::Generators::SpreadsheetGenerator, type: :generator do
|
7
|
+
|
8
|
+
destination File.expand_path("../../tmp", __FILE__)
|
9
|
+
arguments %w(name -m User)
|
10
|
+
|
11
|
+
before(:all) do
|
12
|
+
prepare_destination
|
13
|
+
run_generator
|
14
|
+
end
|
15
|
+
|
16
|
+
it "creates a test initializer" do
|
17
|
+
expect(destination_root).to have_structure do
|
18
|
+
directory 'app' do
|
19
|
+
directory 'spreadsheet_reader' do
|
20
|
+
file 'name_spreadsheet.rb' do
|
21
|
+
contains 'class NameSpreadsheet'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/spec/row_collection_spec.rb
CHANGED
@@ -1,46 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
2
|
+
require_relative 'spreadsheets/invalid_column_spreadsheet'
|
3
|
+
require_relative 'spreadsheets/user_spreadsheet'
|
4
|
+
require_relative 'spreadsheets/user_invalid_spreadsheet'
|
5
|
+
require_relative 'spreadsheets/empty_column_spreadsheet.rb'
|
6
6
|
|
7
7
|
describe RailsSpreadsheetReader::RowCollection do
|
8
8
|
|
9
|
-
it 'empty
|
9
|
+
it 'New collection should be empty' do
|
10
10
|
collection = RailsSpreadsheetReader::RowCollection.new
|
11
11
|
expect(collection.rows).to eq([])
|
12
12
|
expect(collection.invalid?).to eq(false)
|
13
13
|
expect(collection.valid?).to eq(true)
|
14
|
-
expect(collection.errors).to eq(
|
14
|
+
expect(collection.errors).to eq([])
|
15
15
|
end
|
16
16
|
|
17
|
-
it '
|
17
|
+
it 'Pushed rows should be saved into the collection' do
|
18
18
|
collection = RailsSpreadsheetReader::RowCollection.new
|
19
|
-
|
20
|
-
collection
|
19
|
+
row = UserSpreadsheet.new
|
20
|
+
collection << row
|
21
21
|
expect(collection.rows.count).to eq(1)
|
22
|
+
expect(collection.rows.first).to eq(row)
|
22
23
|
end
|
23
24
|
|
24
|
-
it '
|
25
|
-
collection = RailsSpreadsheetReader::RowCollection.new
|
26
|
-
user_spreadsheet = UserSpreadsheet.new
|
27
|
-
user_spreadsheet.make_invalid
|
28
|
-
expect(user_spreadsheet.invalid?).to eq(true)
|
29
|
-
collection.push(user_spreadsheet)
|
30
|
-
expect(collection.valid?).to eq(false)
|
31
|
-
expect(collection.invalid?).to eq(true)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'set_invalid_row' do
|
25
|
+
it 'A collection with an invalid row should be invalid' do
|
35
26
|
collection = RailsSpreadsheetReader::RowCollection.new
|
36
27
|
row = UserSpreadsheet.new
|
37
|
-
|
38
|
-
|
39
|
-
collection
|
40
|
-
collection.set_invalid_row(row, model)
|
28
|
+
row.make_invalid
|
29
|
+
expect(row.invalid?).to eq(true)
|
30
|
+
collection << row
|
41
31
|
expect(collection.valid?).to eq(false)
|
42
32
|
expect(collection.invalid?).to eq(true)
|
43
|
-
expect(collection.invalid_row).to_not eq(nil)
|
44
33
|
end
|
45
34
|
|
46
35
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -18,6 +18,10 @@
|
|
18
18
|
require File.expand_path('../../lib/rails_spreadsheet_reader', __FILE__)
|
19
19
|
TEST_DIR = File.join(File.dirname(__FILE__), 'files')
|
20
20
|
|
21
|
+
require_relative 'db/database'
|
22
|
+
|
23
|
+
Dir["#{File.dirname(__FILE__)}/spreadsheets/*.rb"].each {|file| require file }
|
24
|
+
|
21
25
|
RSpec.configure do |config|
|
22
26
|
# The settings below are suggested to provide a good initial experience
|
23
27
|
# with RSpec, but feel free to customize to your heart's content.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class CustomPersistSpreadsheet < RailsSpreadsheetReader::Base
|
2
|
+
|
3
|
+
attr_accessor :employee_name, :enterprise_name
|
4
|
+
validates_presence_of :employee_name, :enterprise_name
|
5
|
+
|
6
|
+
def self.headers
|
7
|
+
%w(employee_name enterprise_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.models
|
11
|
+
[Enterprise, Employee]
|
12
|
+
end
|
13
|
+
|
14
|
+
def employee
|
15
|
+
{ name: employee_name }
|
16
|
+
end
|
17
|
+
|
18
|
+
def enterprise
|
19
|
+
{ name: enterprise_name }
|
20
|
+
end
|
21
|
+
|
22
|
+
def persist
|
23
|
+
enterprise = Enterprise.find_or_create_by(name: enterprise_name)
|
24
|
+
Employee.create!(name: enterprise_name, enterprise: enterprise)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class EmployeeEnterpriseSpreadsheet < RailsSpreadsheetReader::Base
|
2
|
+
|
3
|
+
attr_accessor :employee_name, :enterprise_name
|
4
|
+
validates_presence_of :employee_name, :enterprise_name
|
5
|
+
|
6
|
+
def self.headers
|
7
|
+
%w(employee_name enterprise_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.models
|
11
|
+
[Enterprise, Employee]
|
12
|
+
end
|
13
|
+
|
14
|
+
def employee
|
15
|
+
{ name: employee_name, enterprise: Enterprise.find_by(name: enterprise_name) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def enterprise
|
19
|
+
{ name: enterprise_name }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class StudentBenefitSpreadsheet < RailsSpreadsheetReader::Base
|
2
|
+
|
3
|
+
attr_accessor :student_name, :benefit_name, :code
|
4
|
+
|
5
|
+
validates_presence_of :student_name, :benefit_name, :code
|
6
|
+
|
7
|
+
def self.headers
|
8
|
+
%w(student_name benefit_name code)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.models
|
12
|
+
[Student, Benefit]
|
13
|
+
end
|
14
|
+
|
15
|
+
def student
|
16
|
+
{ name: student_name, code: code }
|
17
|
+
end
|
18
|
+
|
19
|
+
def benefit
|
20
|
+
{ name: benefit_name, code: code }
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class UserInvalidSpreadsheet < RailsSpreadsheetReader::Base
|
2
|
+
|
3
|
+
attr_accessor :username, :email, :gender, :birthday
|
4
|
+
|
5
|
+
validates_presence_of :username
|
6
|
+
validate :uniqueness_of_username
|
7
|
+
|
8
|
+
def self.headers
|
9
|
+
{ :username => 0, :email => 1, :gender => 2, :birthday => 3 }
|
10
|
+
end
|
11
|
+
|
12
|
+
def uniqueness_of_username
|
13
|
+
if collection.present?
|
14
|
+
detected = collection.rows.find{|r| r.username == self.username and r.row_number < row_number }
|
15
|
+
errors.add(:username, "Username already defined in excel at row #{detected.row_number}") if detected.present?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
{username: username, email: email, gender: gender, birthday: birthday}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -1,15 +1,19 @@
|
|
1
1
|
class UserSpreadsheet < RailsSpreadsheetReader::Base
|
2
2
|
|
3
|
-
attr_accessor :username, :email, :gender
|
3
|
+
attr_accessor :username, :email, :gender, :name
|
4
4
|
|
5
5
|
validates_presence_of :username, :email
|
6
6
|
|
7
|
-
def self.
|
7
|
+
def self.headers
|
8
8
|
{ :username => 0, :email => 1, :gender => 2 }
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.models
|
12
|
+
User
|
13
|
+
end
|
14
|
+
|
11
15
|
def make_invalid
|
12
|
-
|
16
|
+
self.record_with_error = User.make_invalid
|
13
17
|
end
|
14
18
|
|
15
19
|
end
|
data/spec/user_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe User do
|
4
|
+
|
5
|
+
it 'Making an invalid user' do
|
6
|
+
user = User.make_invalid
|
7
|
+
expect(user.valid?).to eq(false)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'Making a valid user' do
|
11
|
+
user = User.make_valid
|
12
|
+
expect(user.valid?).to eq(true)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'Creating a user twice should fail' do
|
16
|
+
user1 = User.make_valid
|
17
|
+
user2 = User.make_valid
|
18
|
+
expect(user1.save).to eq(true)
|
19
|
+
expect(user2.save).to eq(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_spreadsheet_reader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- muzk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '4.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: generator_spec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.9'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.9'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: roo
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +142,23 @@ files:
|
|
114
142
|
- lib/rails_spreadsheet_reader/version.rb
|
115
143
|
- rails_spreadsheet_reader.gemspec
|
116
144
|
- spec/base_spec.rb
|
145
|
+
- spec/db/database.rb
|
146
|
+
- spec/files/employee_enterprise.csv
|
147
|
+
- spec/files/student_benefit.csv
|
148
|
+
- spec/files/student_benefit_invalid.csv
|
117
149
|
- spec/files/users.csv
|
118
150
|
- spec/files/users_invalid.csv
|
119
|
-
- spec/
|
120
|
-
- spec/models/invalid_column_spreadsheet.rb
|
121
|
-
- spec/models/user_invalid_spreadsheet.rb
|
122
|
-
- spec/models/user_spreadsheet.rb
|
151
|
+
- spec/lib/generators/generator_spec.rb
|
123
152
|
- spec/row_collection_spec.rb
|
124
153
|
- spec/spec_helper.rb
|
154
|
+
- spec/spreadsheets/custom_persist_spreadsheet.rb
|
155
|
+
- spec/spreadsheets/employee_enterprise_spreadsheet.rb
|
156
|
+
- spec/spreadsheets/empty_column_spreadsheet.rb
|
157
|
+
- spec/spreadsheets/invalid_column_spreadsheet.rb
|
158
|
+
- spec/spreadsheets/student_benefit_spreadsheet.rb
|
159
|
+
- spec/spreadsheets/user_invalid_spreadsheet.rb
|
160
|
+
- spec/spreadsheets/user_spreadsheet.rb
|
161
|
+
- spec/user_spec.rb
|
125
162
|
homepage: https://github.com/HasuSoftware/rails_spreadsheet_reader
|
126
163
|
licenses:
|
127
164
|
- MIT
|
@@ -148,11 +185,20 @@ specification_version: 4
|
|
148
185
|
summary: Provides an easy way to add model-based validations to excel files.
|
149
186
|
test_files:
|
150
187
|
- spec/base_spec.rb
|
188
|
+
- spec/db/database.rb
|
189
|
+
- spec/files/employee_enterprise.csv
|
190
|
+
- spec/files/student_benefit.csv
|
191
|
+
- spec/files/student_benefit_invalid.csv
|
151
192
|
- spec/files/users.csv
|
152
193
|
- spec/files/users_invalid.csv
|
153
|
-
- spec/
|
154
|
-
- spec/models/invalid_column_spreadsheet.rb
|
155
|
-
- spec/models/user_invalid_spreadsheet.rb
|
156
|
-
- spec/models/user_spreadsheet.rb
|
194
|
+
- spec/lib/generators/generator_spec.rb
|
157
195
|
- spec/row_collection_spec.rb
|
158
196
|
- spec/spec_helper.rb
|
197
|
+
- spec/spreadsheets/custom_persist_spreadsheet.rb
|
198
|
+
- spec/spreadsheets/employee_enterprise_spreadsheet.rb
|
199
|
+
- spec/spreadsheets/empty_column_spreadsheet.rb
|
200
|
+
- spec/spreadsheets/invalid_column_spreadsheet.rb
|
201
|
+
- spec/spreadsheets/student_benefit_spreadsheet.rb
|
202
|
+
- spec/spreadsheets/user_invalid_spreadsheet.rb
|
203
|
+
- spec/spreadsheets/user_spreadsheet.rb
|
204
|
+
- spec/user_spec.rb
|
@@ -1,24 +0,0 @@
|
|
1
|
-
class UserInvalidSpreadsheet < RailsSpreadsheetReader::Base
|
2
|
-
|
3
|
-
attr_accessor :username, :email, :gender
|
4
|
-
|
5
|
-
validates_presence_of :username
|
6
|
-
|
7
|
-
def self.columns
|
8
|
-
{ :username => 0, :email => 1, :gender => 2 }
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.validate_multiple_rows(row_collection)
|
12
|
-
usernames = {}
|
13
|
-
row_collection.rows.each do |row|
|
14
|
-
if usernames.has_key?(row.username)
|
15
|
-
row_collection.invalid_row = row
|
16
|
-
row.errors[:username] = 'is unique'
|
17
|
-
break
|
18
|
-
else
|
19
|
-
usernames[row.username] = true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|