Class: CsvMapper::RowMap

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

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_attributesObject (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

#cursorObject

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 parser_options(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