Skip to content

Commit f2104b5

Browse files
committed
Add failsafe measures to CSVConverter
Fixes #1685
1 parent 177f32a commit f2104b5

3 files changed

Lines changed: 36 additions & 10 deletions

File tree

lib/rails_admin/support/csv_converter.rb

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,24 @@
33

44
module RailsAdmin
55
class CSVConverter
6-
def initialize(objects = [], schema = {})
6+
def initialize(objects = [], schema = nil)
77
@fields = []
88
@associations = []
9+
schema ||= {}
910

1011
return self if (@objects = objects).blank?
1112

1213
@model = objects.dup.first.class
1314
@abstract_model = RailsAdmin::AbstractModel.new(@model)
1415
@model_config = @abstract_model.config
1516
@methods = [(schema[:only] || []) + (schema[:methods] || [])].flatten.compact
16-
@fields = @methods.collect { |m| export_fields_for(m).first }
17+
@fields = @methods.collect { |m| export_field_for(m) }.compact
1718
@empty = ::I18n.t('admin.export.empty_value_for_associated_objects')
1819
schema_include = schema.delete(:include) || {}
1920

2021
@associations = schema_include.each_with_object({}) do |(key, values), hash|
21-
association = association_for(key)
22+
association = export_field_for(key)
23+
next unless association&.association?
2224
model_config = association.associated_model_config
2325
abstract_model = model_config.abstract_model
2426
methods = [(values[:only] || []) + (values[:methods] || [])].flatten.compact
@@ -28,7 +30,7 @@ def initialize(objects = [], schema = {})
2830
model: abstract_model.model,
2931
abstract_model: abstract_model,
3032
model_config: model_config,
31-
fields: methods.collect { |m| export_fields_for(m, model_config).first },
33+
fields: methods.collect { |m| export_field_for(m, model_config) }.compact,
3234
}
3335
hash
3436
end
@@ -61,12 +63,8 @@ def to_csv(options = {})
6163

6264
private
6365

64-
def association_for(key)
65-
export_fields_for(key).detect(&:association?)
66-
end
67-
68-
def export_fields_for(method, model_config = @model_config)
69-
model_config.export.fields.select { |f| f.name == method }
66+
def export_field_for(method, model_config = @model_config)
67+
model_config.export.fields.detect { |f| f.name == method }
7068
end
7169

7270
def generate_csv_string(options)

spec/integration/actions/export_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@
9292
end
9393
end
9494

95+
it 'does not break when nothing is checked' do
96+
visit export_path(model_name: 'comment')
97+
all('input[type="checkbox"]').each(&:uncheck)
98+
expect { click_button 'Export to csv' }.not_to raise_error
99+
end
100+
95101
context 'with csv format' do
96102
it 'exports with modified schema' do
97103
page.driver.post(export_path(model_name: 'player', schema: @non_default_schema, csv: true, all: true, csv_options: {generator: {col_sep: ','}}))

spec/rails_admin/support/csv_converter_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,28 @@
1717
expect(RailsAdmin::CSVConverter.new(objects, schema).to_csv({})[2]).to match(/Number,Name/)
1818
end
1919

20+
describe '#generate_csv_header' do
21+
let(:objects) { FactoryBot.create_list :player, 1 }
22+
before do
23+
RailsAdmin.config(Player) do
24+
export do
25+
field :number
26+
field :name
27+
end
28+
end
29+
end
30+
31+
it 'does not break when non-existent fields are given' do
32+
expect(RailsAdmin::CSVConverter.new(objects, {only: [:name, :foo], include: {bar: :baz}}).send(:generate_csv_header)).
33+
to eq ["Name"]
34+
end
35+
36+
it 'does not break when non-association fields are given to :include' do
37+
expect(RailsAdmin::CSVConverter.new(objects, {only: [:name, :foo], include: {name: :name}}).send(:generate_csv_header)).
38+
to eq ["Name"]
39+
end
40+
end
41+
2042
describe '#to_csv' do
2143
before do
2244
RailsAdmin.config(Player) do

0 commit comments

Comments
 (0)