Module: CsvMapper
- Extended by:
- CsvMapper
- Included in:
- CsvMapper
- Defined in:
- lib/csv-mapper.rb,
lib/csv-mapper/row_map.rb,
lib/csv-mapper/attribute_map.rb
Overview
This module provides the main interface for importing CSV files & data to mapped Ruby objects.
Usage
Including CsvMapper will provide two methods:
-
import
-
map_csv
See csv-mapper.rb for method docs.
Import From File
results = import('/path/to/file.csv') do
# declare mapping here
end
Import From String or IO
results = import(csv_data, :type => :io) do
# declare mapping here
end
Mapping
Mappings are built inside blocks. All three of CsvMapper’s main API methods accept a block containing a mapping. Maps are defined by using map_to
, start_at_row
, before_row
, and after_row
(methods on CsvMapper::RowMap) and by defining your own mapping attributes. A mapping block uses an internal cursor to keep track of the order the mapping attributes are declared and use that order to know the corresponding CSV column index to associate with the attribute.
The Basics
-
map_to
- Override the default Struct target. Accepts a class and an optional hash of default attribute names and values. -
start_at_row
- Specify what row to begin parsing at. Use this to skip headers. -
before_row
- Accepts an Array of method name symbols or lambdas to be invoked before parsing each row. -
after_row
- Accepts an Array of method name symbols or lambdas to be invoked after parsing each row. -
delimited_by
- Accepts a character to be used to delimit columns. Use this to specify pipe-delimited files. -
_SKIP_
- Use as a placehold to skip a CSV column index. -
parser_options
- Accepts a hash of FasterCSV options. Can be anything FasterCSV::new() understands
Attribute Mappings
Attribute mappings are created by using the name of the attribute to be mapped to.
The order in which attribute mappings are declared determines the index of the corresponding CSV row.
All mappings begin at the 0th index of the CSV row.
foo # maps the 0th CSV row position value to the value of the 'foo' attribute on the target object.
# maps the 1st row position to 'bar'
This could also be a nice one liner for easy CSV format conversion
[foo, ] # creates the same attribute maps as above.
The mapping index may be specifically declared in two additional ways:
foo(2) # maps the 2nd CSV row position value to 'foo' and moves the cursor to 3
# maps the 3rd CSV row position to 'bar' due to the current cursor position
baz.at(0) # maps the 0th CSV row position to 'baz' but only increments the cursor 1 position to 4
Each attribute mapping may be configured to parse the record using a lambda or a method name
foo.map lambda{|row| row[2].strip } # maps the 2nd row position value with leading and trailing whitespace removed to 'foo'.
.map :clean_bar # maps the result of the clean_bar method to 'bar'. clean_bar must accept the row as a parameter.
Attribute mapping declarations and “modifiers” may be chained
foo.at(4).map :some_transform
Create Reusable Mappings
The import
method accepts an instance of RowMap as an optional mapping parameter.
The easiest way to create an instance of a RowMap is by using map_csv
.
a_row_map = map_csv do
# declare mapping here
end
Then you can reuse the mapping
results = import(some_string, :type => :io, :map => a_row_map)
other_results = import('/path/to/file.csv', :map => a_row_map)
Defined Under Namespace
Classes: AttributeMap, RowMap
Instance Method Summary collapse
-
#import(data, options = {}, &map_block) ⇒ Object
Load CSV data and map the values according to the definition in the given block.
-
#map_csv(&map_block) ⇒ Object
Create a new RowMap instance from the definition in the given block.
Instance Method Details
#import(data, options = {}, &map_block) ⇒ Object
Load CSV data and map the values according to the definition in the given block. Accepts either a file path, String, or IO as data
. Defaults to file path.
The following options
may be used:
:type
-
defaults to
:file_path
. Use:io
to specify data as String or IO. :map
-
Specify an instance of a RowMap to take presidence over a given block defintion.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/csv-mapper.rb', line 97 def import(data, ={}, &map_block) csv_data = [:type] == :io ? data : File.new(data, 'r') config = { :type => :file_path, :map => map_csv_with_data(csv_data, &map_block) }.merge!() map = config[:map] results = [] FasterCSV.new(csv_data, map. ).each_with_index do |row, i| results << map.parse(row) if i >= map.start_at_row && i <= map.stop_at_row end results end |