diff --git a/lib/rails_admin/support/csv_converter.rb b/lib/rails_admin/support/csv_converter.rb index 7438f845c..df4f75a1c 100644 --- a/lib/rails_admin/support/csv_converter.rb +++ b/lib/rails_admin/support/csv_converter.rb @@ -70,13 +70,21 @@ def export_field_for(method, model_config = @model_config) def generate_csv_string(options) generator_options = (options[:generator] || {}).symbolize_keys.delete_if { |_, value| value.blank? } - method = @objects.respond_to?(:find_each) ? :find_each : :each CSV.generate(**generator_options) do |csv| csv << generate_csv_header unless options[:skip_header] - @objects.send(method) do |object| - csv << generate_csv_row(object) + if @objects.respond_to?(:page) + page_num = 1 + loop do + batch = @objects.page(page_num) + break if batch.blank? + + batch.each { |object| csv << generate_csv_row(object) } + page_num += 1 + end + else + @objects.each { |object| csv << generate_csv_row(object) } end end end diff --git a/spec/rails_admin/support/csv_converter_spec.rb b/spec/rails_admin/support/csv_converter_spec.rb index e0e1198e9..021fc1fc1 100644 --- a/spec/rails_admin/support/csv_converter_spec.rb +++ b/spec/rails_admin/support/csv_converter_spec.rb @@ -150,5 +150,34 @@ expect(subject[2]).to eq("\n") end end + + context 'when more than one page of objects' do + before do + FactoryBot.create_list :player, 100 + end + + let(:objects) { Player.all } + let(:options) { {} } + + it 'generates a csv with all objects' do + expect(subject[2].split("\n").count).to be 101 + end + end + + context 'when objects are ordered' do + before do + FactoryBot.create_list :player, 2 do |player, index| + player.name = "Player #{index}" + end + FactoryBot.create :player, name: 'Player zzz' + end + + let(:objects) { Player.all.order(name: :desc) } + let(:options) { {} } + + it 'preserves the ordering' do + expect(subject[2].split("\n")[1]).to include('Player zzz') + end + end end end