lib/csv_row_model/concerns/attributes_base.rb
require 'csv_row_model/concerns/model/attributes'
require 'csv_row_model/concerns/hidden_module'
# Shared between Import and Export, see test fixture for basic setup
module CsvRowModel
module AttributesBase
extend ActiveSupport::Concern
include Model::Attributes
include HiddenModule
# @return [Hash] a map of `column_name => public_send(column_name)`
def attributes
attributes_from_method_names self.class.column_names
end
# Export:
# source_value - row_model.column1 --> source_model.column1
# formatted_value - format_cell(source_value)
# vale - formatted_value
#
# Import:
# source_value - form source_row
# formatted_value - format_cell(source_value)
# value - calculated_value from a bunch of stuff
ATTRIBUTE_METHODS = {
original_attributes: :value, # a map of `column_name => original_attribute(column_name)`
formatted_attributes: :formatted_value, # a map of `column_name => format_cell(column_name, ...)`
source_attributes: :source_value # a map of `column_name => source (source_row[index_of_column_name] or row_model.public_send(column_name)) `
}.freeze
ATTRIBUTE_METHODS.each do |method_name, attribute_method|
define_method(method_name) do
column_names_to_attribute_value(self.class.column_names, attribute_method)
end
end
# @return [Object] the column's attribute (the csv_row_model default value to be used for import/export)
def original_attribute(column_name)
attribute_objects[column_name].try(:value)
end
def to_json
attributes.to_json
end
def eql?(other)
other.try(:attributes) == attributes
end
def hash
attributes.hash
end
protected
def attributes_from_method_names(column_names)
array_to_block_hash(column_names) { |column_name| try(column_name) }
end
def column_names_to_attribute_value(column_names, attribute_method)
array_to_block_hash(column_names) { |column_name| attribute_objects[column_name].public_send(attribute_method)}
end
def array_to_block_hash(array, &block)
array.zip(array.map(&block)).to_h
end
class_methods do
protected
# See {Model#column}
def column(column_name, options={})
super
define_attribute_method(column_name)
end
# Define default attribute method for a column
# @param column_name [Symbol] the cell's column_name
def define_attribute_method(column_name, &block)
return if method_defined? column_name
define_proxy_method(column_name, &block)
end
def ensure_attribute_method
self.column_names.each { |*args| define_attribute_method(*args) }
end
end
end
end