require 'csv'
class Admin::ExportsController < ApplicationController
include ActionController::Live
def snips
response.headers['Content-Type'] = 'text/csv'
response.headers['Content-Disposition'] = 'attachment; filename="snips.csv"'
response.stream.write(CSV.generate_line(%w[id title author views]))
Snip.includes(:author).find_each(batch_size: 1000) do |snip|
response.stream.write(CSV.generate_line([snip.id, snip.title, snip.author.nickname, snip.views]))
end
rescue IOError
# client disconnected
ensure
response.stream.close
end
end
Large CSV exports should not allocate huge strings. Use ActionController::Live to stream rows. Include a heartbeat and handle client disconnects gracefully. This is real-world Rails ops code.