Class: CsvMapper::RowMap
- Inherits:
-
Object
- Object
- CsvMapper::RowMap
- Defined in:
- lib/csv-mapper.rb
Overview
CsvMapper::RowMap provides a simple, DSL-like interface for constructing mappings. A CsvMapper::RowMap provides the main functionality of the library. It will mostly be used indirectly through the CsvMapper API, but may be useful to use directly for the dynamic CSV mappings.
Constant Summary collapse
- Infinity =
1.0/0
Instance Attribute Summary collapse
-
#mapped_attributes ⇒ Object
readonly
Returns the value of attribute mapped_attributes.
Instance Method Summary collapse
-
#_SKIP_ ⇒ Object
Convenience method to ‘move’ the cursor skipping the current index.
-
#add_attribute(name, index = nil) ⇒ Object
Add a new attribute to this map.
-
#after_row(*afters) ⇒ Object
Declare method name symbols and/or lambdas to be executed before each row.
-
#before_row(*befores) ⇒ Object
Declare method name symbols and/or lambdas to be executed before each row.
-
#cursor ⇒ Object
The current cursor location.
-
#delimited_by(delimiter = nil) ⇒ Object
Specify the CSV column delimiter.
-
#initialize(context, &map_block) ⇒ RowMap
constructor
Create a new instance with access to an evaluation context.
-
#map_to(klass, defaults = {}) ⇒ Object
Each row of a CSV is parsed and mapped to a new instance of a Ruby class; OpenStruct by default.
-
#move_cursor(positions = 1) ⇒ Object
Move the cursor relative to it’s current position.
-
#parse(csv_row) ⇒ Object
Given a CSV row return an instance of an object defined by this mapping.
-
#parser_options(opts = nil) ⇒ Object
Specify a hash of FasterCSV options to be used for CSV parsing.
-
#start_at_row(row_number = nil) ⇒ Object
Declare what row to begin parsing the CSV.
-
#stop_at_row(row_number = nil) ⇒ Object
Declare the last row to be parsed in a CSV.
Constructor Details
#initialize(context, &map_block) ⇒ RowMap
Create a new instance with access to an evaluation context
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/csv-mapper.rb', line 110 def initialize(context, &map_block) @context = context @before_filters = [] @after_filters = [] @parser_options = {} @start_at_row = 0 @stop_at_row = Infinity @delimited_by = FasterCSV::DEFAULT_OPTIONS[:col_sep] @mapped_attributes = [] self.instance_eval(&map_block) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object (protected)
The Hacktastic “magic” Used to dynamically create CsvMapper::AttributeMaps based on unknown method calls that should represent the names of mapped attributes.
An optional first argument is used to move this maps cursor position and as the index of the new AttributeMap
223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/csv-mapper.rb', line 223 def method_missing(name, *args) # :nodoc: if index = args[0] self.move_cursor(index - self.cursor) else index = self.cursor self.move_cursor end add_attribute(name, index) end |
Instance Attribute Details
#mapped_attributes ⇒ Object (readonly)
Returns the value of attribute mapped_attributes.
107 108 109 |
# File 'lib/csv-mapper.rb', line 107 def mapped_attributes @mapped_attributes end |
Instance Method Details
#_SKIP_ ⇒ Object
Convenience method to ‘move’ the cursor skipping the current index.
145 146 147 |
# File 'lib/csv-mapper.rb', line 145 def _SKIP_ self.move_cursor end |
#add_attribute(name, index = nil) ⇒ Object
Add a new attribute to this map. Mostly used internally, but is useful for dynamic map creation. returns the newly created CsvMapper::AttributeMap
184 185 186 187 188 |
# File 'lib/csv-mapper.rb', line 184 def add_attribute(name, index=nil) attr_mapping = CsvMapper::AttributeMap.new(name.to_sym, index, @context) self.mapped_attributes << attr_mapping attr_mapping end |
#after_row(*afters) ⇒ Object
Declare method name symbols and/or lambdas to be executed before each row. Each method or lambda must accept to parameters: csv_row
, target_object
Methods names should refer to methods available within the RowMap’s provided context
178 179 180 |
# File 'lib/csv-mapper.rb', line 178 def after_row(*afters) self.add_filters(@after_filters, *afters) end |
#before_row(*befores) ⇒ Object
Declare method name symbols and/or lambdas to be executed before each row. Each method or lambda must accept to parameters: csv_row
, target_object
Methods names should refer to methods available within the RowMap’s provided context
171 172 173 |
# File 'lib/csv-mapper.rb', line 171 def before_row(*befores) self.add_filters(@before_filters, *befores) end |
#cursor ⇒ Object
The current cursor location
191 192 193 |
# File 'lib/csv-mapper.rb', line 191 def cursor # :nodoc: @cursor ||= 0 end |
#delimited_by(delimiter = nil) ⇒ Object
Specify the CSV column delimiter. Defaults to comma.
150 151 152 153 |
# File 'lib/csv-mapper.rb', line 150 def delimited_by(delimiter=nil) @delimited_by = delimiter if delimiter @delimited_by end |
#map_to(klass, defaults = {}) ⇒ Object
Each row of a CSV is parsed and mapped to a new instance of a Ruby class; OpenStruct by default. Use this method to change the what class each row is mapped to.
The given class must respond to a parameter-less #new and all attribute mappings defined. Providing a hash of defaults will ensure that each resulting object will have the providing name and attribute values unless overridden by a mapping
128 129 130 131 132 133 134 |
# File 'lib/csv-mapper.rb', line 128 def map_to(klass, defaults={}) @map_to_klass = klass defaults.each do |name, value| self.add_attribute(name, -99).map lambda{|row| value} end end |
#move_cursor(positions = 1) ⇒ Object
Move the cursor relative to it’s current position
196 197 198 |
# File 'lib/csv-mapper.rb', line 196 def move_cursor(positions=1) # :nodoc: self.cursor += positions end |
#parse(csv_row) ⇒ Object
Given a CSV row return an instance of an object defined by this mapping
201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/csv-mapper.rb', line 201 def parse(csv_row) target = self.map_to_class.new @before_filters.each {|filter| filter.call(csv_row, target) } self.mapped_attributes.inject(target) do |result, attr_map| result.send("#{attr_map.name}=".to_sym, attr_map.parse(csv_row)) result end @after_filters.each {|filter| filter.call(csv_row, target) } return target end |
#parser_options(opts = nil) ⇒ Object
Specify a hash of FasterCSV options to be used for CSV parsing
Can be anything FasterCSV::new() accepts
139 140 141 142 |
# File 'lib/csv-mapper.rb', line 139 def (opts=nil) @parser_options = opts if opts @parser_options.merge :col_sep => @delimited_by end |
#start_at_row(row_number = nil) ⇒ Object
Declare what row to begin parsing the CSV. This is useful for skipping headers and such.
157 158 159 160 |
# File 'lib/csv-mapper.rb', line 157 def start_at_row(row_number=nil) @start_at_row = row_number if row_number @start_at_row end |
#stop_at_row(row_number = nil) ⇒ Object
Declare the last row to be parsed in a CSV.
163 164 165 166 |
# File 'lib/csv-mapper.rb', line 163 def stop_at_row(row_number=nil) @stop_at_row = row_number if row_number @stop_at_row end |