3

I am trying to get ALL the filtered results when exporting to CSV.

My to_csv is working fine, and I suspect something to do with my controller.

Search around with kaminari, ransack, but seems like even exporting to csv is rare using ransack.
Any help is much appreciated.

controller.rb

@search = Order.includes(:user, :order_items).ransack(params[:q])
@orders = @search.result.order(created_at: :desc).page(params[:page])

respond_to do  
  |format|
  format.html
  format.csv { send_data @orders.to_csv, filename: "orders-#{DateTime.now.strftime("%d%m%Y%H%M")}.csv" }
end

view.html.haml

= link_to 'Download as CSV', a_o_path(request.params.merge(format: 'csv')), { class: 'btn btn-primary', style: 'float: right;' }
Iqlaas Ismail
  • 385
  • 7
  • 21
  • 1
    You are merging the request params right? So the q params will get submitted as well, resulting in Ransack performing the search before rendering the csv. Why don't you just call: `a_o_path(:format => :csv)` – bo-oz Jan 19 '18 at 09:41
  • @bo-oz Sorry, that did not seem to work. Request merge is to get the filtered results. – Iqlaas Ismail Jan 19 '18 at 09:52
  • Yes, but you need to get rid of the parameters that are causing kaminari to kick in. If you'd debug the call to the controller methiod, you'd see that @orders contains only first x orders, due to pagination. That then gets passed to the csv view. You get exactly what you ask for. – bo-oz Jan 19 '18 at 10:38

1 Answers1

5

You can do this with ransack and kaminari, but you'll need to update your controller just a bit. Here's what you have so far:

format.csv { send_data @orders.to_csv, filename: "orders-#{DateTime.now.strftime("%d%m%Y%H%M")}.csv" }

When your controller gets here, @orders has been filtered by ransack, but it has also been paginated by kaminari. Since you're responding with html in some cases and csv in others, you'll want to do something slightly different when you respond with csv.

Here's what I would try:

@search = Order.includes(:user, :order_items).ransack(params[:q])
@orders = @search.result.order(created_at: :desc)

respond_to do |format|
  format.html { @orders = @orders.page(params[:page]) }
  format.csv { send_data @orders.to_csv, filename: "orders-#{DateTime.now.strftime("%d%m%Y%H%M")}.csv" }
end

Basically, you only paginate the query when you respond with html. When csv is requested, all of the orders will still be there.

Derek Hopper
  • 2,110
  • 12
  • 19