Blair Anderson
Blair Anderson

Reputation: 20161

Ruby/Rails: CSV column specific converters

I have a CSV and using the default CSV library would like to apply different converters to different columns

headers are:

units_at_warehouse(#integer),
  external_id(#string),
    released(#date),
      list_price_cents(#integer)

I am current using these options:

options = {
  headers: true, 
  converters: nil, 
  header_converters: :symbol
}

CSV.foreach(file, options) do |row|
  # current my best option is:
  convert_integers(row)
  convert_dates(row)
  persist(row)#...saving
end

Is it possible to pass in a converter PER column?

Something like:

options = {
  headers: true, 
  header_converters: :symbol,
  converters: {
    units_at_warehouse: :numeric,
    list_price_cents: :numeric,
    released: :date
  }
}

Upvotes: 5

Views: 767

Answers (1)

Edward Anderson
Edward Anderson

Reputation: 13916

Though CSV doesn't provide such an interface, it does allow you to specify multiple converters to try. It only applies each filter when a value matches the that filter's expected format.

Therefore you can specify both converters in your options, and CSV will intelligently apply them whenever a column's value matches the format for an integer or date.

converters: [:integer, :date]

The downside to their approach is that it will also convert dates and integers in other columns rather than leaving them as strings.

If you need to get around this limitation, you can provide a lambda converter that takes 2 parameters, where the 2nd parameter is a CSV::FieldInfo that contains the header, aka what column the value is in, and apply conversions only to specific columns.

Upvotes: 2

Related Questions