Class: TalltyImportExport::Import

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Import

Returns a new instance of Import.



6
7
8
9
# File 'lib/tallty_import_export/import.rb', line 6

def initialize klass
  @klass = klass
  @context = Context.new({})
end

Instance Attribute Details

#associationsObject (readonly)

Returns the value of attribute associations.



4
5
6
# File 'lib/tallty_import_export/import.rb', line 4

def associations
  @associations
end

#contextObject (readonly)

Returns the value of attribute context.



4
5
6
# File 'lib/tallty_import_export/import.rb', line 4

def context
  @context
end

#klassObject (readonly)

Returns the value of attribute klass.



4
5
6
# File 'lib/tallty_import_export/import.rb', line 4

def klass
  @klass
end

#primary_keysObject (readonly)

Returns the value of attribute primary_keys.



4
5
6
# File 'lib/tallty_import_export/import.rb', line 4

def primary_keys
  @primary_keys
end

Instance Method Details

#convert_data(line_info) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/tallty_import_export/import.rb', line 76

def convert_data line_info
  line_info.with_indifferent_access.reduce({}) do |h, (k, v)|
    header = @headers.find do |_header|
      _header[:key].to_sym == k.to_sym
    end
    # header[:convert] = handle_xxx
    # handle_xxx(val, processing_line_info, raw_line_info)
    val = header[:convert] ? send(header[:convert], v, h, line_info) : v
    if header[:json]
      h[header[:json]] ||= {}
      h[header[:json]][k] = val
    else
      h[k.to_sym] = val
    end
    h
  end.with_indifferent_access
end

#import_data(data, associations, **options) ⇒ Object



41
42
43
44
45
46
# File 'lib/tallty_import_export/import.rb', line 41

def import_data data, associations, **options
  process_options(options)
  TalltyImportExport::Excel::Rows.new(data).each_with_excel_hash(@excel_hash) do |line_info|
    process_line_info(line_info, associations)
  end
end

#import_headers(**args) ⇒ Object



103
104
105
# File 'lib/tallty_import_export/import.rb', line 103

def import_headers **args
  @headers || klass.try(:headers) || klass.try(:model_headers) || (raise ArgumentError.new('missing import_headers'))
end

#import_headers_resultObject



99
100
101
# File 'lib/tallty_import_export/import.rb', line 99

def import_headers_result
  @headers || import_headers
end

#import_record(line_info, associations) ⇒ Object

这个方法是可以由复杂业务进行重载的 ###



136
137
138
139
140
141
142
143
# File 'lib/tallty_import_export/import.rb', line 136

def import_record line_info, associations
  if primary_keys.present?
    _record = associations.find_or_initialize_by(line_info.clone.extract!(*primary_keys))
    _record.update!(line_info.clone.except!(*primary_keys))
  else
    associations.create!(line_info)
  end
end

#import_xlsx(xlsx_file, associations, **options) ⇒ Object

xlsx_file 为 file path or file object or TalltyImportExport::Excel.new



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/tallty_import_export/import.rb', line 20

def import_xlsx xlsx_file, associations, **options
  @associations = associations
  # 先处理获取出来Excel每行的数据, line_info
  process_options(options)

  if TalltyImportExport::Excel === xlsx_file
    xlsx_file.rows.each_with_excel_hash(@excel_hash) do |line_info|
      process_line_info(line_info, associations)
    end
  else
    file_path = xlsx_file.is_a?(String) ? xlsx_file : xlsx_file.path
    xlsx = ::Roo::Excelx.new(file_path)
    xlsx.each_with_pagename do |_sheetname, sheet|
      sheet.each(**@excel_hash).with_index do |line_info, index|
        next if index == 0
        process_line_info(line_info, associations)
      end
    end
  end
end

#process_line_info(line_info, associations) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/tallty_import_export/import.rb', line 65

def process_line_info line_info, associations
  # 转换处理导入的数据格式
  line_info = convert_data(line_info)

  # 处理每行对于导入的动作,处理line_info
  return unless valid?(line_info)

  import_record(line_info, associations)
  context.last_line_info = line_info
end

#process_options(options) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/tallty_import_export/import.rb', line 52

def process_options options
  options = options.with_indifferent_access
  @headers = options.delete(:headers) || import_headers
  @primary_keys = options.delete(:primary_keys) || @headers.map { |header| header[:primary_key] ? header[:key].to_sym : nil }.compact

  @excel_hash = @headers.reduce({}) do |h, header|
    h[header[:key].to_sym] = header[:name]
    h
  end

  options
end

#skip(val, processing_line_info, raw_line_info) ⇒ Object

# 只保留 key, name, json, 合并到 import_header def headers= val

if val.empty?
  @headers = import_headers_result.map { |header| header.with_indifferent_access }
  return
end

key_to_coming_header = val.reduce({}) do |out, header|
  out[header.with_indifferent_access[:key].to_sym] = header.with_indifferent_access
  out
end

result = []
val.map do |header|
  if (exist_header = import_headers_result.find { |model_header| model_header[:key] === header[:key] })
    result.push(exist_header.merge(header.compact))
  else
    result.push(header)
  end
end

@headers = result

end



131
132
133
# File 'lib/tallty_import_export/import.rb', line 131

def skip val, processing_line_info, raw_line_info
  # do nothing there, use for header[:convert]
end

#tallty_excelObject



48
49
50
# File 'lib/tallty_import_export/import.rb', line 48

def tallty_excel
  TalltyImportExport::Excel
end

#valid?(line_info) ⇒ Boolean

通过转换后,数据是否合法,如果不合法,则直接跳过不处理这个数据

Returns:

  • (Boolean)


95
96
97
# File 'lib/tallty_import_export/import.rb', line 95

def valid? line_info
  true
end