Rails - Combine search, pagination and export in Rails
Let’s see how combine the search, pagination and export options in Rails.
For the pagination, I’ve decided to use the kaminari gem. It provides a very easy way to add pagination into Rails. I’ve used it over will_paginate as kaminari
includes (for free) some methods for the view
pages. It also has the posibility of use some themes to the pagination component displayed in the view.
Regarding the search and export, it will be done using ruby
code.
Let’s see the code!
NOTE: Update to use model params
!!Better than extract the params inside the model method.
In the view: app/views/bits/index.html.erb
# search component
<%= form_tag({}, method: :get) do %>
<%= text_field_tag(:path, params[:path]) %>
<%= submit_tag 'Search' %>
<% end %>
<% @bits.each do |bit| %>
# do whatever you need here with the data
...
<% end %>
# pagination
<div>
<%= paginate @bits %>
</div>
# export
<div id="export">
<button><%= link_to("Export results in csv", bits_path(path: controller.params["path"], format: :csv)) %></button>
<button><%= link_to("Export results in xls", bits_path(path: controller.params["path"], format: :xls)) %></button>
</div>
Note: Mention the form_tag
has two parameters:
- path
method
used. Eg::get
If you indicate the path (eg: form_tag(bits_path, method: :get)
), you will get redirected to the bits_path
in the model. In case you don’t indicate any path (eg: form_tag({}, method: :get)
), you are redirected to the same same path you currently are.
In the controller: app/controllers/bits_controller.rb
def index
@bits = Bit.search(bits_params)
respond_to do |format|
format.html { render :index }
format.xls { send_data generate_xls(@bits), filename: "Export-#{Date.today}.xls" }
format.csv { send_data generate_csv(@bits), filename: "Export-#{Date.today}.csv" }
end
end
private
# define the params permited
def bits_params
params.permit(:path, :page, :format).to_h.symbolize_keys
end
Where the methods generate_xls
and generate_csv
are defined as private methods in the controller.
In the model we define the method search()
: app/models/bit.rb
def self.search(path: nil, page: nil, format: nil)
search_query = if path
where("path LIKE ? ", "%#{path}%")
else
all
end
if format
# export
search_query.find_in_batches
else
# display it with pagination
search_query.page(page)
end
end