Class: RailsAdmin::CSVConverter

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_admin/support/csv_converter.rb

Instance Method Summary collapse

Constructor Details

#initialize(objects = [], schema = {}) ⇒ CSVConverter

Returns a new instance of CSVConverter.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rails_admin/support/csv_converter.rb', line 11

def initialize(objects = [], schema = {})
  return self if (@objects = objects).blank?

  @model = objects.first.class
  @abstract_model = RailsAdmin::AbstractModel.new(@model)
  @model_config = @abstract_model.config
  @methods = [(schema[:only] || []) + (schema[:methods] || [])].flatten.compact
  @fields = @model_config.export.fields.select{|f| @methods.include? f.name }
  @empty = ::I18n.t('admin.export.empty_value_for_associated_objects')
  @associations = {}

  (schema.delete(:include) || {}).each do |key, values|
    association = @model_config.export.fields.find{|f| f.name == key && f.association?}
    model_config = association.associated_model_config
    abstract_model = model_config.abstract_model
    model = abstract_model.model
    methods = [(values[:only] || []) + (values[:methods] || [])].flatten.compact
    fields = model_config.export.fields.select{|f| methods.include? f.name }

    @associations[key] = {
      :association => association,
      :model => model,
      :abstract_model => abstract_model,
      :model_config => model_config,
      :fields => fields
    }
  end
end

Instance Method Details

#to_csv(options) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rails_admin/support/csv_converter.rb', line 40

def to_csv(options)
  options ||= {}
  return '' if @objects.blank?

  # encoding shenanigans first
  @encoding_from = if [nil, '', 'utf8', 'utf-8', 'UTF8', 'UTF-8'].include?(encoding = @abstract_model.encoding)
    'UTF-8'
  else
    encoding
  end

  unless options[:encoding_to].blank?
    @encoding_to = options[:encoding_to]
    unless @encoding_to == @encoding_from
      require 'iconv'
      @iconv = (Iconv.new("#{@encoding_to}//TRANSLIT//IGNORE", @encoding_from) rescue (Rails.logger.error("Iconv cannot convert to #{@encoding_to}: #{$!}\nNo conversion will take place"); nil))
    end
  else
    @encoding_to = @encoding_from
  end

  csv_string = CSVClass.generate(options[:generator] ? options[:generator].symbolize_keys.delete_if {|key, value| value.blank? } : {}) do |csv|
    unless options[:skip_header]
      csv << @fields.map do |field|
        output(::I18n.t('admin.export.csv.header_for_root_methods', :name => field.label, :model => @abstract_model.pretty_name))
      end +
      @associations.map do |association_name, option_hash|
        option_hash[:fields].map do |field|
          output(::I18n.t('admin.export.csv.header_for_association_methods', :name => field.label, :association => option_hash[:association].label))
        end
      end.flatten
    end
    @objects.each do |o|


      csv << @fields.map do |field|
        output(field.with(:object => o).export_value)
      end +
      @associations.map do |association_name, option_hash|

        associated_objects = [o.send(association_name)].flatten.compact
        option_hash[:fields].map do |field|
          output(associated_objects.map{ |ao| field.with(:object => ao).export_value.presence || @empty }.join(','))
        end
      end.flatten
    end
  end

  # Add a BOM for utf8 encodings, helps with utf8 auto-detect for some versions of Excel.
  # Don't add if utf8 but user don't want to touch input encoding:
  # If user chooses utf8, he will open it in utf8 and BOM will disappear at reading.
  # But that way "English" users who don't bother and chooses to let utf8 by default won't get BOM added
  # and will not see it if Excel opens the file with a different encoding.
  csv_string = "\xEF\xBB\xBF#{csv_string.respond_to?(:force_encoding) ? csv_string.force_encoding('UTF-8') : csv_string}" if options[:encoding_to] == 'UTF-8'
  csv_string = ((@iconv ? @iconv.iconv(csv_string) : csv_string) rescue str) if @encoding_to =~ NON_ASCII_ENCODINGS # global conversion for non ASCII encodings
  [!options[:skip_header], @encoding_to, csv_string]
end