Class: RelationalExporter::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/relational_exporter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Runner

Returns a new instance of Runner.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/relational_exporter.rb', line 11

def initialize(options={})
  # TODO - disable when not byebugging!!!
  ActiveRecord::Base.logger = Logger.new(STDOUT)

  @connection_config = options[:connection_config]
  begin
    ActiveRecord::Base.establish_connection @connection_config
    ActiveRecord::Base.connection.active?
  rescue Exception => e
    raise "Database connection failed: #{e.message}"
  end

  @schema = Hashie::Mash.new(options[:schema] || YAML.load_file(options[:schema_file]))

  load_models
end

Instance Attribute Details

#schemaObject

Returns the value of attribute schema.



9
10
11
# File 'lib/relational_exporter.rb', line 9

def schema
  @schema
end

Instance Method Details

#export(output_config, &block) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
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
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/relational_exporter.rb', line 28

def export(output_config, &block)
  output_config = Hashie::Mash.new output_config

  main_klass = output_config.output.model.to_s.classify.constantize

  main_klass.set_scope_from_hash output_config.output.scope.as_json

  header_row = []
  max_associations = {}

  ::CSV.open('/tmp/test.csv', 'wb', headers: true) do |csv|
    main_klass.all.find_in_batches do |batch|
      batch.each do |single|
        if block_given?
          yield single
        end

        row = []

        # Add main record headers
        single.attributes.each do |field, value|
          header_row << [main_klass.to_s.underscore, field].join('_').classify if csv.header_row?
          row << value
        end

        output_config.output.associations.each do |association_accessor, association_options|
          association_accessor = association_accessor.to_s.to_sym
          association_klass = association_accessor.to_s.classify.constantize
          scope = symbolize_options association_options.scope

          associated = single.send association_accessor
          # TODO - this might suck for single associations (has_one) because they don't return an ar::associations::collectionproxy
          associated = associated.find_all_by_scope(scope) unless scope.blank? || !associated.respond_to?(:find_all_by_scope)

          if associated.is_a? Hash
            associated = [ associated ]
          elsif associated.blank?
            associated = []
          end

          foreign_key = main_klass.reflections[association_accessor].foreign_key rescue nil

          fields = association_klass.first.attributes.keys

          fields.reject! {|v| v == foreign_key } if foreign_key

          if csv.header_row?
            case main_klass.reflections[association_accessor].macro
            when :has_many
              max_associated = association_klass.find_all_by_scope(scope)
                                                .joins(main_klass.table_name.to_sym)
                                                .order('count_all desc')
                                                .group(foreign_key)
                                                .limit(1).count.flatten[1]
            when :has_one
              max_associated = 1
            end

            max_associations[association_accessor] = max_associated

            max_associated.times do |i|
              fields.each do |field|
                header_row << [association_klass.to_s.underscore, i+1, field].join('_').classify
              end
            end
          end

          get_row_arr(associated, fields, max_associations[association_accessor]) {|field| row << field}
        end

        csv << header_row if csv.header_row?
        if row.count != header_row.count
          puts "OH SHIT, this row is not right!"
          byebug
        end
        csv << row
      end
    end
  end
end