5

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
  }
}

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.