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
-
#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
Copy a ActiveModel::Model errors.
-
#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.
98 99 100 101 102 103 104 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 98 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
#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.
191 192 193 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 191 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.
48 49 50 51 52 53 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 48 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.
78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 78 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
159 160 161 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 159 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
155 156 157 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 155 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
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 173 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.
28 29 30 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 28 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
128 129 130 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 128 def self.validate_multiple_rows(row_collection) end |
Instance Method Details
#copy_errors(model) ⇒ Object
Copy a ActiveModel::Model errors
17 18 19 20 21 |
# File 'lib/rails_spreadsheet_reader/base.rb', line 17 def copy_errors(model) model.errors..each do |msg| errors.add(:base, msg) end end |