rails_admin_import 0.1.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{RELEASE_NOTES → CHANGELOG.md} +0 -0
- data/MIT-LICENSE +1 -1
- data/README.md +193 -50
- data/Rakefile +8 -32
- data/app/views/rails_admin/main/_results.html.haml +18 -0
- data/app/views/rails_admin/main/_section.html.haml +10 -0
- data/app/views/rails_admin/main/import.html.haml +72 -0
- data/config/locales/import.en.yml +39 -0
- data/lib/rails_admin_import/action.rb +45 -0
- data/lib/rails_admin_import/config/legacy_model.rb +42 -0
- data/lib/rails_admin_import/config/sections/import.rb +30 -0
- data/lib/rails_admin_import/config.rb +16 -37
- data/lib/rails_admin_import/formats/csv_importer.rb +75 -0
- data/lib/rails_admin_import/formats/dummy_importer.rb +16 -0
- data/lib/rails_admin_import/formats/file_importer.rb +45 -0
- data/lib/rails_admin_import/formats/json_importer.rb +31 -0
- data/lib/rails_admin_import/formats.rb +28 -0
- data/lib/rails_admin_import/import_logger.rb +7 -4
- data/lib/rails_admin_import/import_model.rb +94 -0
- data/lib/rails_admin_import/importer.rb +224 -0
- data/lib/rails_admin_import/rails_admin_plugin.rb +23 -0
- data/lib/rails_admin_import/version.rb +1 -1
- data/lib/rails_admin_import.rb +5 -39
- metadata +83 -13
- data/app/views/rails_admin/main/import.html.erb +0 -143
- data/lib/rails_admin_import/config/base.rb +0 -62
- data/lib/rails_admin_import/config/model.rb +0 -23
- data/lib/rails_admin_import/import.rb +0 -218
@@ -0,0 +1,75 @@
|
|
1
|
+
require "csv"
|
2
|
+
require "rchardet"
|
3
|
+
|
4
|
+
module RailsAdminImport
|
5
|
+
module Formats
|
6
|
+
class CSVImporter < FileImporter
|
7
|
+
Formats.register(:csv, self)
|
8
|
+
|
9
|
+
# Default is to downcase headers and add underscores to convert into attribute names
|
10
|
+
HEADER_CONVERTER = lambda do |header|
|
11
|
+
header.parameterize.underscore
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(import_model, params)
|
15
|
+
super
|
16
|
+
@encoding = params[:encoding]
|
17
|
+
@header_converter = RailsAdminImport.config.header_converter || HEADER_CONVERTER
|
18
|
+
end
|
19
|
+
|
20
|
+
# A method that yields a hash of attributes for each record to import
|
21
|
+
def each_record
|
22
|
+
CSV.foreach(filename, csv_options) do |row|
|
23
|
+
yield convert_to_attributes(row)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def csv_options
|
30
|
+
{
|
31
|
+
headers: true,
|
32
|
+
header_converters: @header_converter
|
33
|
+
}.tap do |options|
|
34
|
+
add_encoding!(options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_encoding!(options)
|
39
|
+
from_encoding =
|
40
|
+
if !@encoding.blank?
|
41
|
+
@encoding
|
42
|
+
else
|
43
|
+
detect_encoding
|
44
|
+
end
|
45
|
+
|
46
|
+
to_encoding = import_model.abstract_model.encoding
|
47
|
+
if from_encoding && from_encoding != to_encoding
|
48
|
+
options[:encoding] = "#{from_encoding}:#{to_encoding}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def detect_encoding
|
53
|
+
charset = CharDet.detect File.read(filename)
|
54
|
+
if charset["confidence"] > 0.6
|
55
|
+
from_encoding = charset["encoding"]
|
56
|
+
from_encoding = "UTF-8" if from_encoding == "ascii"
|
57
|
+
end
|
58
|
+
from_encoding
|
59
|
+
end
|
60
|
+
|
61
|
+
def convert_to_attributes(row)
|
62
|
+
row.each_with_object({}) do |(field, value), record|
|
63
|
+
break if field.nil?
|
64
|
+
field = field.to_sym
|
65
|
+
if import_model.has_multiple_values?(field)
|
66
|
+
field = import_model.pluralize_field(field)
|
67
|
+
(record[field] ||= []) << value
|
68
|
+
else
|
69
|
+
record[field] = value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RailsAdminImport
|
2
|
+
module Formats
|
3
|
+
class FileImporter
|
4
|
+
def initialize(import_model, params)
|
5
|
+
if params.has_key?(:file)
|
6
|
+
@filename = params[:file].tempfile
|
7
|
+
end
|
8
|
+
@import_model = import_model
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :filename, :error, :import_model
|
12
|
+
|
13
|
+
def valid?
|
14
|
+
if filename.nil?
|
15
|
+
@error = I18n.t("admin.import.missing_file")
|
16
|
+
false
|
17
|
+
else
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
return enum_for(:each) unless block_given?
|
24
|
+
|
25
|
+
if RailsAdminImport.config.logging && filename
|
26
|
+
copy_uploaded_file_to_log_dir
|
27
|
+
end
|
28
|
+
|
29
|
+
each_record(&block)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def each_record
|
35
|
+
raise "Implement each_record in subclasses"
|
36
|
+
end
|
37
|
+
|
38
|
+
def copy_uploaded_file_to_log_dir
|
39
|
+
copy_filename = "#{Time.now.strftime("%Y-%m-%d-%H-%M-%S")}-import.csv"
|
40
|
+
copy_path = File.join(Rails.root, "log", "import", copy_filename)
|
41
|
+
FileUtils.copy(filename, copy_path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RailsAdminImport
|
2
|
+
module Formats
|
3
|
+
class JSONImporter < FileImporter
|
4
|
+
Formats.register(:json, self)
|
5
|
+
|
6
|
+
# A method that yields a hash of attributes for each record to import
|
7
|
+
def each_record
|
8
|
+
File.open(filename) do |file|
|
9
|
+
data = JSON.load(file)
|
10
|
+
|
11
|
+
if data.is_a? Hash
|
12
|
+
# Load array from root key
|
13
|
+
data = data[root_key]
|
14
|
+
end
|
15
|
+
|
16
|
+
if !data.is_a? Array
|
17
|
+
raise ArgumentError, I18n.t("admin.import.invalid_json", root_key: root_key)
|
18
|
+
end
|
19
|
+
|
20
|
+
data.each do |record|
|
21
|
+
yield record.symbolize_keys
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def root_key
|
27
|
+
import_model.model.model_name.element.pluralize
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RailsAdminImport
|
2
|
+
module Formats
|
3
|
+
class << self
|
4
|
+
def register(format, klass)
|
5
|
+
@registry[format.to_s] = klass
|
6
|
+
end
|
7
|
+
|
8
|
+
def for(format, *args)
|
9
|
+
@registry.fetch(format.to_s, DummyImporter).new(*args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def all
|
13
|
+
@registry.keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset
|
17
|
+
@registry = {}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
reset
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require "rails_admin_import/formats/dummy_importer"
|
26
|
+
require "rails_admin_import/formats/file_importer"
|
27
|
+
require "rails_admin_import/formats/csv_importer"
|
28
|
+
require "rails_admin_import/formats/json_importer"
|
@@ -2,13 +2,16 @@ module RailsAdminImport
|
|
2
2
|
class ImportLogger
|
3
3
|
attr_reader :logger
|
4
4
|
|
5
|
-
def initialize(log_file_name =
|
6
|
-
|
5
|
+
def initialize(log_file_name = "rails_admin_import.log")
|
6
|
+
if RailsAdminImport.config.logging
|
7
|
+
@logger = Logger.new(File.join(Rails.root, "log", log_file_name))
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
11
|
def info(message)
|
10
|
-
|
12
|
+
if RailsAdminImport.config.logging
|
13
|
+
@logger.info message
|
14
|
+
end
|
11
15
|
end
|
12
|
-
|
13
16
|
end
|
14
17
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module RailsAdminImport
|
2
|
+
class AssociationNotFound < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class ImportModel
|
6
|
+
def initialize(abstract_model)
|
7
|
+
@abstract_model = abstract_model
|
8
|
+
@config = abstract_model.config.import
|
9
|
+
@model = abstract_model.model
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :abstract_model, :model, :config
|
13
|
+
|
14
|
+
def display_name
|
15
|
+
abstract_model.config.label
|
16
|
+
end
|
17
|
+
|
18
|
+
def label_for_model(object)
|
19
|
+
object.public_send(label_method)
|
20
|
+
end
|
21
|
+
|
22
|
+
def label_method
|
23
|
+
@label_method ||= abstract_model.config.object_label_method
|
24
|
+
end
|
25
|
+
|
26
|
+
def importable_fields(model_config = config)
|
27
|
+
@importable_fields ||= {}
|
28
|
+
@importable_fields[model_config] ||= model_config.visible_fields.reject do |f|
|
29
|
+
# Exclude id, created_at and updated_at
|
30
|
+
model_config.default_excluded_fields.include? f.name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def model_fields(model_config = config)
|
35
|
+
@model_fields ||= {}
|
36
|
+
@model_fields[model_config] ||= importable_fields(model_config).select { |f|
|
37
|
+
!f.association? || f.association.polymorphic?
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def association_fields
|
42
|
+
@association_fields ||= importable_fields.select { |f|
|
43
|
+
f.association? && !f.association.polymorphic?
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def belongs_to_fields
|
48
|
+
@belongs_to_fields ||= association_fields.select { |f|
|
49
|
+
!f.multiple?
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def many_fields
|
54
|
+
@many_fields ||= association_fields.select {
|
55
|
+
|f| f.multiple?
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def associated_object(field, mapping_field, value)
|
60
|
+
klass = association_class(field)
|
61
|
+
klass.where(mapping_field => value).first or
|
62
|
+
raise AssociationNotFound, "#{klass}.#{mapping_field} = #{value}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def association_class(field)
|
66
|
+
field.association.klass
|
67
|
+
end
|
68
|
+
|
69
|
+
def associated_config(field)
|
70
|
+
field.associated_model_config.import
|
71
|
+
end
|
72
|
+
|
73
|
+
def associated_model_fields(field)
|
74
|
+
@associated_fields ||= {}
|
75
|
+
@associated_fields[field] ||= associated_config(field).visible_fields.select { |f|
|
76
|
+
!f.association?
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def has_multiple_values?(field_name)
|
81
|
+
plural_name = pluralize_field(field_name)
|
82
|
+
many_fields.any? { |field| field.name == field_name || field.name == plural_name }
|
83
|
+
end
|
84
|
+
|
85
|
+
def pluralize_field(field_name)
|
86
|
+
@plural_fields ||= many_fields.map(&:name).each_with_object({}) { |name, h|
|
87
|
+
h[name.to_s.singularize.to_sym] = name
|
88
|
+
}
|
89
|
+
@plural_fields[field_name] || field_name
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require "rails_admin_import/import_logger"
|
2
|
+
|
3
|
+
module RailsAdminImport
|
4
|
+
class Importer
|
5
|
+
def initialize(import_model, params)
|
6
|
+
@import_model = import_model
|
7
|
+
@params = params
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :import_model, :params
|
11
|
+
|
12
|
+
class UpdateLookupError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
def import(records)
|
16
|
+
begin
|
17
|
+
init_results
|
18
|
+
|
19
|
+
# TODO: re-implement file size check
|
20
|
+
# if file_check.readlines.size > RailsAdminImport.config.line_item_limit
|
21
|
+
# return results = { :success => [], :error => ["Please limit upload file to #{RailsAdminImport.config.line_item_limit} line items."] }
|
22
|
+
# end
|
23
|
+
|
24
|
+
with_transaction do
|
25
|
+
records.each do |record|
|
26
|
+
import_record(record)
|
27
|
+
end
|
28
|
+
|
29
|
+
rollback_if_error
|
30
|
+
end
|
31
|
+
rescue Exception => e
|
32
|
+
report_general_error("#{e} (#{e.backtrace.first})")
|
33
|
+
end
|
34
|
+
|
35
|
+
format_results
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def init_results
|
41
|
+
@results = { :success => [], :error => [] }
|
42
|
+
end
|
43
|
+
|
44
|
+
def with_transaction(&block)
|
45
|
+
if RailsAdminImport.config.rollback_on_error &&
|
46
|
+
defined?(ActiveRecord)
|
47
|
+
|
48
|
+
ActiveRecord::Base.transaction &block
|
49
|
+
else
|
50
|
+
block.call
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def rollback_if_error
|
55
|
+
if RailsAdminImport.config.rollback_on_error &&
|
56
|
+
defined?(ActiveRecord) &&
|
57
|
+
!results[:error].empty?
|
58
|
+
|
59
|
+
results[:success] = []
|
60
|
+
raise ActiveRecord::Rollback
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def import_record(record)
|
65
|
+
if update_lookup && !record.has_key?(update_lookup)
|
66
|
+
raise UpdateLookupError, I18n.t("admin.import.missing_update_lookup")
|
67
|
+
end
|
68
|
+
|
69
|
+
object = find_or_create_object(record, update_lookup)
|
70
|
+
action = object.new_record? ? :create : :update
|
71
|
+
|
72
|
+
begin
|
73
|
+
import_belongs_to_data(object, record)
|
74
|
+
import_has_many_data(object, record)
|
75
|
+
rescue AssociationNotFound => e
|
76
|
+
error = I18n.t("admin.import.association_not_found", :error => e.to_s)
|
77
|
+
report_error(object, action, error)
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
81
|
+
perform_model_callback(object, :before_import_save, record)
|
82
|
+
|
83
|
+
if object.save
|
84
|
+
report_success(object, action)
|
85
|
+
perform_model_callback(object, :after_import_save, record)
|
86
|
+
else
|
87
|
+
report_error(object, action, object.errors.full_messages.join(", "))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def update_lookup
|
92
|
+
@update_lookup ||= if params[:update_if_exists] == "1"
|
93
|
+
params[:update_lookup].to_sym
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
attr_reader :results
|
98
|
+
|
99
|
+
def logger
|
100
|
+
@logger ||= ImportLogger.new
|
101
|
+
end
|
102
|
+
|
103
|
+
def report_success(object, action)
|
104
|
+
object_label = import_model.label_for_model(object)
|
105
|
+
message = I18n.t("admin.import.import_success.#{action}",
|
106
|
+
:name => object_label)
|
107
|
+
logger.info "#{Time.now}: #{message}"
|
108
|
+
results[:success] << message
|
109
|
+
end
|
110
|
+
|
111
|
+
def report_error(object, action, error)
|
112
|
+
object_label = import_model.label_for_model(object)
|
113
|
+
message = I18n.t("admin.import.import_error.#{action}",
|
114
|
+
:name => object_label,
|
115
|
+
:error => error)
|
116
|
+
logger.info "#{Time.now}: #{message}"
|
117
|
+
results[:error] << message
|
118
|
+
end
|
119
|
+
|
120
|
+
def report_general_error(error)
|
121
|
+
message = I18n.t("admin.import.import_error.general", :error => error)
|
122
|
+
logger.info "#{Time.now}: #{message}"
|
123
|
+
results[:error] << message
|
124
|
+
end
|
125
|
+
|
126
|
+
def format_results
|
127
|
+
imported = results[:success]
|
128
|
+
not_imported = results[:error]
|
129
|
+
unless imported.empty?
|
130
|
+
results[:success_message] = format_result_message("successful", imported)
|
131
|
+
end
|
132
|
+
unless not_imported.empty?
|
133
|
+
results[:error_message] = format_result_message("error", not_imported)
|
134
|
+
end
|
135
|
+
|
136
|
+
results
|
137
|
+
end
|
138
|
+
|
139
|
+
def format_result_message(type, array)
|
140
|
+
result_count = "#{array.size} #{import_model.display_name.pluralize(array.size)}"
|
141
|
+
I18n.t("admin.flash.#{type}",
|
142
|
+
name: result_count,
|
143
|
+
action: I18n.t("admin.actions.import.done"))
|
144
|
+
end
|
145
|
+
|
146
|
+
def perform_model_callback(object, method_name, record)
|
147
|
+
if object.respond_to?(method_name)
|
148
|
+
# Compatibility: Old import hook took 2 arguments.
|
149
|
+
# Warn and call with a blank hash as 2nd argument.
|
150
|
+
if object.method(method_name).arity == 2
|
151
|
+
report_old_import_hook(method_name)
|
152
|
+
object.send(method_name, record, {})
|
153
|
+
else
|
154
|
+
object.send(method_name, record)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def report_old_import_hook(method_name)
|
160
|
+
unless @old_import_hook_reported
|
161
|
+
error = I18n.t("admin.import.import_error.old_import_hook",
|
162
|
+
model: import_model.display_name,
|
163
|
+
method: method_name)
|
164
|
+
report_general_error(error)
|
165
|
+
@old_import_hook_reported = true
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def find_or_create_object(record, update)
|
170
|
+
field_names = import_model.model_fields.map(&:name)
|
171
|
+
new_attrs = record.select do |field_name, value|
|
172
|
+
field_names.include?(field_name) && !value.blank?
|
173
|
+
end
|
174
|
+
|
175
|
+
model = import_model.model
|
176
|
+
object = if update.present?
|
177
|
+
model.find_by(update => record[update])
|
178
|
+
end
|
179
|
+
|
180
|
+
if object.nil?
|
181
|
+
object = model.new(new_attrs)
|
182
|
+
else
|
183
|
+
object.attributes = new_attrs.except(update.to_sym)
|
184
|
+
end
|
185
|
+
object
|
186
|
+
end
|
187
|
+
|
188
|
+
def import_belongs_to_data(object, record)
|
189
|
+
import_model.belongs_to_fields.each do |field|
|
190
|
+
mapping_key = params[:associations][field.name]
|
191
|
+
value = extract_mapping(record[field.name], mapping_key)
|
192
|
+
|
193
|
+
if !value.blank?
|
194
|
+
object.send "#{field.name}=", import_model.associated_object(field, mapping_key, value)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def import_has_many_data(object, record)
|
200
|
+
import_model.many_fields.each do |field|
|
201
|
+
if record.has_key? field.name
|
202
|
+
mapping_key = params[:associations][field.name]
|
203
|
+
values = record[field.name].reject { |value| value.blank? }.map { |value|
|
204
|
+
extract_mapping(value, mapping_key)
|
205
|
+
}
|
206
|
+
|
207
|
+
if !values.empty?
|
208
|
+
associated = values.map { |value| import_model.associated_object(field, mapping_key, value) }
|
209
|
+
object.send "#{field.name}=", associated
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def extract_mapping(value, mapping_key)
|
216
|
+
if value.is_a? Hash
|
217
|
+
value[mapping_key]
|
218
|
+
else
|
219
|
+
value
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Load the Rails Admin gem if not already done
|
2
|
+
require "rails_admin"
|
3
|
+
|
4
|
+
# Add the Import action
|
5
|
+
require "rails_admin_import/action"
|
6
|
+
|
7
|
+
# Add the import configuration section for models
|
8
|
+
require "rails_admin_import/config/sections/import"
|
9
|
+
|
10
|
+
# Register the configuration adapter for Rails Admin
|
11
|
+
# to allow configure_with(:import)
|
12
|
+
module RailsAdminImport
|
13
|
+
module Extension
|
14
|
+
class ConfigurationAdapter < SimpleDelegator
|
15
|
+
def initialize
|
16
|
+
super RailsAdminImport::Config
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
RailsAdmin.add_extension :import, RailsAdminImport::Extension,
|
23
|
+
configuration: true
|
data/lib/rails_admin_import.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require "rails_admin_import/engine"
|
2
|
-
require "rails_admin_import/
|
2
|
+
require "rails_admin_import/import_model"
|
3
|
+
require "rails_admin_import/formats"
|
4
|
+
require "rails_admin_import/importer"
|
3
5
|
require "rails_admin_import/config"
|
6
|
+
require "rails_admin_import/rails_admin_plugin"
|
4
7
|
|
5
8
|
module RailsAdminImport
|
6
9
|
def self.config(entity = nil, &block)
|
7
10
|
if entity
|
8
11
|
RailsAdminImport::Config.model(entity, &block)
|
9
|
-
elsif block_given? && ENV[
|
12
|
+
elsif block_given? && ENV["SKIP_RAILS_ADMIN_INITIALIZER"] != "true"
|
10
13
|
block.call(RailsAdminImport::Config)
|
11
14
|
else
|
12
15
|
RailsAdminImport::Config
|
@@ -18,40 +21,3 @@ module RailsAdminImport
|
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
|
-
require 'rails_admin/config/actions'
|
22
|
-
|
23
|
-
module RailsAdmin
|
24
|
-
module Config
|
25
|
-
module Actions
|
26
|
-
class Import < Base
|
27
|
-
RailsAdmin::Config::Actions.register(self)
|
28
|
-
|
29
|
-
register_instance_option :collection do
|
30
|
-
true
|
31
|
-
end
|
32
|
-
|
33
|
-
register_instance_option :http_methods do
|
34
|
-
[:get, :post]
|
35
|
-
end
|
36
|
-
|
37
|
-
register_instance_option :controller do
|
38
|
-
Proc.new do
|
39
|
-
@response = {}
|
40
|
-
|
41
|
-
if request.post?
|
42
|
-
results = @abstract_model.model.run_import(params)
|
43
|
-
@response[:notice] = results[:success].join("<br />").html_safe if results[:success].any?
|
44
|
-
@response[:error] = results[:error].join("<br />").html_safe if results[:error].any?
|
45
|
-
end
|
46
|
-
|
47
|
-
render :action => @action.template_name
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
register_instance_option :link_icon do
|
52
|
-
'icon-folder-open'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|