module CsvRowModel::Import::Attributes
Constants
- CLASS_TO_PARSE_LAMBDA
Mapping of column type classes to a parsing lambda. These are applied after {Import.format_cell}. Can pass custom Proc with :parse option.
- PARSE_VALIDATION_CLASSES
Classes with a validations associated with them in csv_row_model/validators
Public Instance Methods
return [Hash] a map changes from {.column}‘s default option’: ‘column_name -> [value_before_default, default_set]`
# File lib/csv_row_model/import/attributes.rb, line 52 def default_changes original_attributes @default_changes end
@return [Object] the column’s attribute before override
# File lib/csv_row_model/import/attributes.rb, line 34 def original_attribute(column_name) return @original_attributes[column_name] if original_attribute_memoized? column_name csv_string_model.valid? return nil unless csv_string_model.errors[column_name].blank? value = self.class.format_cell(mapped_row[column_name], column_name, self.class.index(column_name), context) if value.present? value = instance_exec(value, &self.class.parse_lambda(column_name)) elsif self.class.options(column_name)[:default] original_value = value value = instance_exec(value, &self.class.default_lambda(column_name)) @default_changes[column_name] = [original_value, value] end @original_attributes[column_name] = value end
@return [Hash] a map of ‘column_name => original_attribute
(column_name)`
# File lib/csv_row_model/import/attributes.rb, line 28 def original_attributes self.class.column_names.each { |column_name| original_attribute(column_name) } @original_attributes end
Protected Instance Methods
Adds the type validation based on :validate_type option
# File lib/csv_row_model/import/attributes.rb, line 114 def add_type_validation(column_name) options = options(column_name) validate_type = options[:validate_type] return unless validate_type type = options[:type] raise ArgumentError.new("invalid :type given for :validate_type for column") unless PARSE_VALIDATION_CLASSES.include? type validate_type = Proc.new { validates column_name, "#{type.name.underscore}_format".to_sym => true, allow_blank: true } csv_string_model(&validate_type) end
See {Model#column}
# File lib/csv_row_model/import/attributes.rb, line 94 def column(column_name, options={}) super define_attribute_method(column_name) end
@return [Lambda] returns a Lambda: ->(original_value) { default_exists? ? default : original_value }
# File lib/csv_row_model/import/attributes.rb, line 75 def default_lambda(column_name) default = options(column_name)[:default] default.is_a?(Proc) ? ->(s) { instance_exec(&default) } : ->(s) { default.nil? ? s : default } end
Define default attribute method for a column @param column_name [Symbol] the cell’s column_name
# File lib/csv_row_model/import/attributes.rb, line 107 def define_attribute_method(column_name) return if method_defined? column_name add_type_validation(column_name) define_method(column_name) { original_attribute(column_name) } end
Safe to override. Method applied to each cell by default
@param cell [String] the cell’s string @param column_name [Symbol] the cell’s column_name @param column_index [Integer] the column_name’s index
# File lib/csv_row_model/import/attributes.rb, line 70 def format_cell(cell, column_name, column_index, context={}) cell end
# File lib/csv_row_model/import/attributes.rb, line 99 def merge_options(column_name, options={}) original_options = options(column_name) add_type_validation(column_name) if !original_options[:validate_type] && options[:validate_type] super end
# File lib/csv_row_model/import/attributes.rb, line 58 def original_attribute_memoized?(column_name) @original_attributes ||= {} @default_changes ||= {} @original_attributes.has_key? column_name end
@return [Lambda, Proc] returns the Lambda/Proc given in the parse option or: ->(original_value) { parse_proc_exists? ? parsed_value : original_value }
# File lib/csv_row_model/import/attributes.rb, line 82 def parse_lambda(column_name) options = options(column_name) raise ArgumentError.new("You need either :parse OR :type but not both of them") if options[:parse] && options[:type] parse_lambda = options[:parse] || CLASS_TO_PARSE_LAMBDA[options[:type]] return parse_lambda if parse_lambda raise ArgumentError.new("type must be #{CLASS_TO_PARSE_LAMBDA.keys.reject(:nil?).join(", ")}") end