Add local_census_records importation model
This model without database allow us to validate incoming file extension and headers and also does the following during importation process: * Ignore empty rows * Classifiy rows in two groups: created_records, invalid_records
This commit is contained in:
committed by
Javi Martín
parent
0239efef9d
commit
615bfadca8
84
app/models/local_census_records/import.rb
Normal file
84
app/models/local_census_records/import.rb
Normal file
@@ -0,0 +1,84 @@
|
||||
require "csv"
|
||||
|
||||
class LocalCensusRecords::Import
|
||||
include ActiveModel::Model
|
||||
|
||||
ATTRIBUTES = %w[document_type document_number date_of_birth postal_code].freeze
|
||||
ALLOWED_FILE_EXTENSIONS = %w[csv].freeze
|
||||
|
||||
attr_accessor :file, :created_records, :invalid_records
|
||||
|
||||
validates :file, presence: true
|
||||
validate :file_extension, if: -> { @file.present? }
|
||||
validate :file_headers_definition, if: -> { @file.present? && valid_extension? }
|
||||
|
||||
def initialize(attributes = {})
|
||||
if attributes.present?
|
||||
attributes.each do |attr, value|
|
||||
public_send("#{attr}=", value)
|
||||
end
|
||||
end
|
||||
@created_records = []
|
||||
@invalid_records = []
|
||||
end
|
||||
|
||||
def save
|
||||
return false if invalid?
|
||||
|
||||
CSV.open(file.path, headers: true).each do |row|
|
||||
next if empty_row?(row)
|
||||
|
||||
process_row row
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_row(row)
|
||||
local_census_record = build_local_census_record(row)
|
||||
|
||||
if local_census_record.invalid?
|
||||
invalid_records << local_census_record
|
||||
else
|
||||
local_census_record.save
|
||||
created_records << local_census_record
|
||||
end
|
||||
end
|
||||
|
||||
def build_local_census_record(row)
|
||||
local_census_record = LocalCensusRecord.new
|
||||
local_census_record.attributes = row.to_hash.slice(*ATTRIBUTES)
|
||||
local_census_record
|
||||
end
|
||||
|
||||
def empty_row?(row)
|
||||
row.all? { |_, cell| cell.nil? }
|
||||
end
|
||||
|
||||
def file_extension
|
||||
return if valid_extension?
|
||||
|
||||
errors.add :file, :extension, valid_extensions: ALLOWED_FILE_EXTENSIONS.join(", ")
|
||||
end
|
||||
|
||||
def fetch_file_headers
|
||||
CSV.open(file.path, &:readline)
|
||||
end
|
||||
|
||||
def file_headers_definition
|
||||
headers = fetch_file_headers
|
||||
return if headers.all? {|header| ATTRIBUTES.include? header } &&
|
||||
ATTRIBUTES.all? {|attr| headers.include? attr }
|
||||
|
||||
errors.add :file, :headers, required_headers: ATTRIBUTES.join(", ")
|
||||
end
|
||||
|
||||
def valid_extension?
|
||||
ALLOWED_FILE_EXTENSIONS.include? extension
|
||||
end
|
||||
|
||||
def extension
|
||||
File.extname(file.original_filename).delete(".")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user