class CSVImporter::Row
A Row
from the CSV file.
Using the header, the model_klass and the identifier it builds the model to be persisted.
Public Instance Methods
build_model()
click to toggle source
# File lib/csv_importer/row.rb, line 109 def build_model model_klass.new end
csv_attributes()
click to toggle source
A hash with this row’s attributes
# File lib/csv_importer/row.rb, line 30 def csv_attributes @csv_attributes ||= Hash[header.column_names.zip(row_array)] end
errors()
click to toggle source
Error
from the model mapped back to the CSV header if we can
# File lib/csv_importer/row.rb, line 78 def errors Hash[ model.errors.to_hash.map do |attribute, errors| if column_name = header.column_name_for_model_attribute(attribute) [column_name, errors.last] else [attribute, errors.last] end end ] end
find_model()
click to toggle source
# File lib/csv_importer/row.rb, line 94 def find_model return nil if identifiers.nil? model = build_model set_attributes(model) identifiers = model_identifiers(model) return nil if identifiers.empty? query = Hash[ identifiers.map { |identifier| [ identifier, model.public_send(identifier) ] } ] model_klass.find_by(query) end
find_or_build_model()
click to toggle source
# File lib/csv_importer/row.rb, line 90 def find_or_build_model find_model || build_model end
model()
click to toggle source
The model to be persisted
# File lib/csv_importer/row.rb, line 18 def model @model ||= begin model = find_or_build_model set_attributes(model) after_build_blocks.each { |block| instance_exec(model, &block) } model end end
set_attribute(model, column, csv_value)
click to toggle source
Set the attribute using the column_definition and the csv_value
# File lib/csv_importer/row.rb, line 53 def set_attribute(model, column, csv_value) column_definition = column.definition transformer = column_definition.to if transformer.respond_to?(:call) arity = transformer.is_a?(Proc) ? transformer.arity : transformer.method(:call).arity case arity when 1 # to: ->(email) { email.downcase } model.public_send("#{column_definition.name}=", transformer.call(csv_value)) when 2 # to: ->(published, post) { post.published_at = Time.now if published == "true" } transformer.call(csv_value, model) when 3 # to: ->(field_value, post, column) { post.hash_field[column.name] = field_value } transformer.call(csv_value, model, column) else raise ArgumentError, "arity: #{transformer.arity.inspect} - `to` can only have 1, 2 or 3 arguments" end else attribute = column_definition.attribute model.public_send("#{attribute}=", csv_value) end model end
set_attributes(model)
click to toggle source
Set attributes
# File lib/csv_importer/row.rb, line 35 def set_attributes(model) header.columns.each do |column| value = csv_attributes[column.name] begin value = value.dup if value rescue TypeError # can't dup Symbols, Integer etc... end next if column.definition.nil? set_attribute(model, column, value) end model end
skip!()
click to toggle source
# File lib/csv_importer/row.rb, line 113 def skip! self.skip = true end
Private Instance Methods
model_identifiers(model)
click to toggle source
# File lib/csv_importer/row.rb, line 119 def model_identifiers(model) if identifiers.is_a?(Proc) [identifiers.call(model)].flatten else identifiers end end