Class: RailsSpreadsheetReader::Base
- Inherits:
-
Object
- Object
- RailsSpreadsheetReader::Base
- Includes:
- ActiveModel::Model
- Defined in:
- lib/rails_spreadsheet_reader/base.rb
Defined Under Namespace
Classes: InvalidTypeError, MethodNotImplementedError
Instance Attribute Summary collapse
-
#models_with_errors ⇒ Object
Returns the value of attribute models_with_errors.
-
#row_number ⇒ Object
Returns the value of attribute row_number.
Class Method Summary collapse
-
.array_to_hash(arr) ⇒ Object
Transform an array [a0, a1, a2, …] to a Hash { a0 => 0, a1 => 1, etc } which is the format required by the #formatted_hash method.
-
.columns ⇒ Object
Defines the columns of the excel that the class will read.
-
.formatted_hash(array) ⇒ Object
Returns the Hash representation of a given array using self.format method (which internally uses self.columns).
- .open_spreadsheet(spreadsheet_file) ⇒ Object
-
.persist(row_collection) ⇒ Object
This method is called after the self.validate_multiple_rows method only if it have not raised an exception.
-
.read_spreadsheet(spreadsheet_file) ⇒ Object
Read and validates the given #spreadsheet_file.
-
.starting_row ⇒ Object
Defines the starting row of the excel where the class should start reading the data.
-
.validate_multiple_rows(row_collection) ⇒ Object
This method is called when all rows of row_collection are valid.
Instance Method Summary collapse
-
#copy_errors(model) ⇒ Object
Models are added models_with_errors.
- #copy_errors_on_validation ⇒ Object
-
#initialize(arr_or_hash = {}) ⇒ Base
constructor
Generalizes the constructor of ActiveModel::Model to make it work with an array argument.
Constructor Details
#initialize(arr_or_hash = {}) ⇒ Base
Generalizes the constructor of ActiveModel::Model to make it work with an array argument. When an array argument is passed, it calls formatted_hash method to generate a Hash and then pass it to the ActiveModel::Model constructor
Parameters:
- arr_or_hash
-
Array or Hash of values which represents an excel column.
113 114 115 116 117 118 119 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 113 def initialize(arr_or_hash = {}) if arr_or_hash.is_a?(Array) super(self.class.formatted_hash(arr_or_hash)) else super(arr_or_hash) end end |
Instance Attribute Details
#models_with_errors ⇒ Object
Returns the value of attribute models_with_errors.
16 17 18 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 16 def models_with_errors @models_with_errors end |
#row_number ⇒ Object
Returns the value of attribute row_number.
14 15 16 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 14 def row_number @row_number end |
Class Method Details
.array_to_hash(arr) ⇒ Object
Transform an array [a0, a1, a2, …] to a Hash { a0 => 0, a1 => 1, etc } which is the format required by the #formatted_hash method.
206 207 208 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 206 def self.array_to_hash(arr) Hash[[*arr.map { |e| e.to_sym }.map.with_index]] end |
.columns ⇒ Object
Defines the columns of the excel that the class will read. This method must return a Array of strings/symbols (representing columns names) or a Hash (which map column names to columns indexes).
Array Example
def self.columns
[:username, :email, :gender]
end
Hash Example
def self.columns
{ :username => 0, :email => 1, :gender => 2 }
end
Returns:
An Array or a Hash defining the columns of the excel.
63 64 65 66 67 68 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 63 def self.columns fail( MethodNotImplementedError, 'Please implement this method in your class.' ) end |
.formatted_hash(array) ⇒ Object
Returns the Hash representation of a given array using self.format method (which internally uses self.columns). The keys of this Hash are defined in the self.columns method and the values of each key depends on the order of the columns.
For example, given the following self.columns definition
def self.columns
[:username, :email, :gender]
end
Or
def self.columns
{ :username => 0, :email => 1, :gender => 2 }
end
Row.formatted([username [email protected] male]) will return { username: ‘username’, email: ‘[email protected]’, gender: ‘male’ }
Parameters:
- array
-
Array of values which represents an excel column.
Returns:
Hash representation of the given array which maps columns names to the array values.
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 93 def self.formatted_hash(array) if format.keys.count > 0 parsed_row = {} format.each_pair { |key, col| parsed_row[key] = array[col] } return parsed_row end return nil end |
.open_spreadsheet(spreadsheet_file) ⇒ Object
174 175 176 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 174 def self.open_spreadsheet(spreadsheet_file) Roo::Spreadsheet.open(spreadsheet_file) end |
.persist(row_collection) ⇒ Object
This method is called after the self.validate_multiple_rows method only if it have not raised an exception. The idea of this method is to persist the row’s data. If there was an error with a certain row, you have to Rollback the valid transactions, set the invalid error to the row_collection and set the row errors to the row object.
Example: def self.persist(row_collection)
User.transaction do
row_collection.each do |row|
user = User.new(attr1: row.attr1, attr2: row.attr2, ...)
unless user.save
row_collection.set_invalid_row(row, user) # pass the model with errors as second parameter
rollback # use the rollback helper to rollback the transaction.
end
end
end
end
Parameters:
- row_collection
-
SpreadsheetReader::RowCollection instance
170 171 172 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 170 def self.persist(row_collection) end |
.read_spreadsheet(spreadsheet_file) ⇒ Object
Read and validates the given #spreadsheet_file. First calls #validate_rows method which run #ActiveModel::Model.valid? on each row. Then calls #validate_multiple_rows and finally ends with #persist
Parameters:
- spreadsheet_file
-
File instance
Returns:
- row_collection
-
SpreadsheetReader::RowCollection instance
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 188 def self.read_spreadsheet(spreadsheet_file) if columns.empty? raise MethodNotImplementedError end spreadsheet = open_spreadsheet(spreadsheet_file) row_collection = RailsSpreadsheetReader::RowCollection.new validate_rows(spreadsheet, row_collection) validate_multiple_rows(row_collection) if row_collection.valid? persist(row_collection) if row_collection.valid? row_collection end |
.starting_row ⇒ Object
Defines the starting row of the excel where the class should start reading the data.
Returns:
A integer representing the starting row of the data.
43 44 45 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 43 def self.starting_row 2 end |
.validate_multiple_rows(row_collection) ⇒ Object
This method is called when all rows of row_collection are valid. The main idea of this method is to run validations that have to do with the set of rows of the excel. For example, you can check here if a excel column is unique:
Example:
def self.validate_multiple_rows(row_collection)
username_list = []
row_collection.each do |row|
if username_list.include?(row.username)
row_collection.invalid_row = row
row.errors[:username] = 'is unique'
else
username_list << row.username
end
end
end
Parameters:
- row_collection
-
SpreadsheetReader::RowCollection instance
143 144 145 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 143 def self.validate_multiple_rows(row_collection) end |
Instance Method Details
#copy_errors(model) ⇒ Object
Models are added models_with_errors. They will be copied in to self.errors on copy_errors_on_validation callback
33 34 35 36 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 33 def copy_errors(model) self.models_with_errors ||= [] self.models_with_errors << model end |
#copy_errors_on_validation ⇒ Object
22 23 24 25 26 27 28 29 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 22 def copy_errors_on_validation self.models_with_errors ||= [] self.models_with_errors.each do |model| model.errors..each do |msg| errors.add(:base, msg) end end end |