class Decidim::Exporters::CSV

Exports any serialized object (Hash) into a readable CSV. It transforms the columns using slashes in a way that can be afterwards reconstructed into the original nested hash.

For example, `{ name: { ca: “Hola”, en: “Hello” } }` would result into the columns: `name/ca` and `name/es`.

Public Instance Methods

export(col_sep = Decidim.default_csv_col_sep) click to toggle source

Public: Exports a CSV serialized version of the collection using the provided serializer and following the previously described strategy.

Returns an ExportData instance.

# File lib/decidim/exporters/csv.rb, line 18
def export(col_sep = Decidim.default_csv_col_sep)
  data = ::CSV.generate(headers: headers, write_headers: true, col_sep: col_sep) do |csv|
    processed_collection.each do |resource|
      csv << headers.map { |header| custom_sanitize(resource[header]) }
    end
  end
  ExportData.new(data, "csv")
end

Protected Instance Methods

custom_sanitize(value) click to toggle source
# File lib/decidim/exporters/csv.rb, line 29
def custom_sanitize(value)
  # rubocop:disable Style/AndOr
  return value unless value.instance_of?(String) and invalid_first_chars.include?(value.first)

  # rubocop:enable Style/AndOr
  value.dup.prepend("'")
end
invalid_first_chars() click to toggle source
# File lib/decidim/exporters/csv.rb, line 37
def invalid_first_chars
  %w(= + - @)
end

Private Instance Methods

flatten(object, key = nil) click to toggle source
# File lib/decidim/exporters/csv.rb, line 55
def flatten(object, key = nil)
  case object
  when Hash
    object.inject({}) do |result, (subkey, value)|
      new_key = key ? "#{key}/#{subkey}" : subkey.to_s
      result.merge(flatten(value, new_key))
    end
  when Array
    { key.to_s => object.compact.map(&:to_s).join(", ") }
  else
    { key.to_s => object }
  end
end
headers() click to toggle source
# File lib/decidim/exporters/csv.rb, line 43
def headers
  return [] if processed_collection.empty?

  processed_collection.inject([]) { |keys, resource| keys | resource.keys }
end
processed_collection() click to toggle source
# File lib/decidim/exporters/csv.rb, line 49
def processed_collection
  @processed_collection ||= collection.map do |resource|
    flatten(@serializer.new(resource).serialize)
  end
end