module CSVI18n::Ext

Extension to the core ruby CSV class

Public Instance Methods

shift() click to toggle source

Redefine the shift method to catch the exception and attempt to return a translated version of the error message using I18n.t

Calls superclass method
# File lib/csv_i18n/ext.rb, line 6
def shift
  super
rescue ::CSV::MalformedCSVError => exception
  raise $!, translated_exception_message(exception.message), $!.backtrace
end

Private Instance Methods

keyify(msg) click to toggle source

:reek: UtilityFunction but could use parameterize('_') if rails is present

# File lib/csv_i18n/ext.rb, line 50
def keyify(msg)
  msg.gsub(/[^a-z]+/i, ' ').strip.gsub(' ', '_').downcase
end
translatable?() click to toggle source

:reek: UtilityFunction for readability

# File lib/csv_i18n/ext.rb, line 45
def translatable?
  defined?(::I18n) && ::I18n.locale_available?(::I18n.locale)
end
translated_exception_message(msg) click to toggle source

Parse the exception message and attempt to translate it. If no translation is possible, simply return the original error message.

The translation keys need to be defined in your language files as follows.

csv:
  exception:
    field_size_exceeded: "Broken on %{line_number}"
    illegal_quoting:
    missing_or_stray_quote:
    unclosed_quoted_field:
    unquoted_fields_do_not_allow_r_or_n:

:reek: FeatureEnvy because it's clear enough to leave as is :reek: NilCheck because we want certainty with the RegExp match

# File lib/csv_i18n/ext.rb, line 29
def translated_exception_message(msg)
  return msg unless translatable?

  # This will break if the CSV class changes it's error messages
  matches = msg.match(/\s[ion]{2}?\s?\(?line (\d)\)?\.?/i)
  return msg if matches.nil?

  ::I18n.translate(
    keyify(msg.sub(matches[0], '')),
    scope: [:csv, :exception],
    line_number: matches[1],
    default: msg
  )
end