Sha256: 4da8977500dbba5bfe3c430f9a18dcfa5ad8bc22d1d0e85b921b85f959e2d118

Contents?: true

Size: 1.66 KB

Versions: 1

Compression:

Stored size: 1.66 KB

Contents

# frozen_string_literal: true

require "csv"

module Decidim
  module Exporters
    # 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`.
    class CSV < Exporter
      # Public: Exports a CSV serialized version of the collection using the
      # provided serializer and following the previously described strategy.
      #
      # Returns an ExportData instance.
      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| resource[header] }
          end
        end
        ExportData.new(data, "csv")
      end

      private

      def headers
        return [] if processed_collection.empty?

        processed_collection.first.keys
      end

      def processed_collection
        @processed_collection ||= collection.map do |resource|
          flatten(@serializer.new(resource).serialize)
        end
      end

      def flatten(object, key = nil)
        if object.is_a? Hash
          object.inject({}) do |result, (subkey, value)|
            new_key = key ? "#{key}/#{subkey}" : subkey.to_s
            result.merge(flatten(value, new_key))
          end
        elsif object.is_a?(Array)
          { key.to_s => object.compact.map(&:to_s).join(", ") }
        else
          { key.to_s => object }
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
decidim-core-0.22.0 lib/decidim/exporters/csv.rb