ruby-on-railsrubyruby-on-rails-5erbkaminari

Paginating Multiple Objects of the Same Model on the Same Page with Kaminari


Background

In my website, I'm trying to display 2 tables with data that I have scraped from another website and have place into an object called Product. The Product object has 2 categories which are stored as enums, registered and unregistered.

Problem

The problem comes when I apply pagination with Kaminari. Below are some images to demonstrate the problem.

Before the problem:
Before the problem

When I click '2' on the Registered Products table, the Unregistered Products table also goes to '2'

Problem:
Problem

I'm guessing it's because the data from both tables come from the same object? Anyway below are the relevant files.

My Model

class Product < ApplicationRecord
enum product_type: [:registered, :unregistered, :cosmetic]

paginates_per 8
end

My Controller

class HomeController < ApplicationController
 def index
  @registered_products = Product.where(product_type: 0).page params[:page]
  @unregistered_products = Product.where(product_type: 1).page params[:page]
 end
end 

My partial for registered products

<table>
  <thead>
    <tr>
      <th scope='col'>Name</th>
      <th scope='col'>Chemical</th>
    </tr>
  </thead>
  <tbody>
    <% @registered_products.each do |product| %>
      <tr>
        <td><%= product.product_name %></td>
        <td><%= product.chemical %></td>
       </tr>
    <% end %>
  </tbody>
</table>
<%= paginate @registered_products %>

My partial for unregistered products is the same, replace @registered_products with @unregistered products.

index.html.erb

<h2>Registered Products</h2>
<%= render partial: "registered" %>
<h2>Unregistered Products</h2>
<%= render partial: "unregistered" %>

What I tried

I was looking through the Kaminari documentation and noticed that arrays can be paginated. So I tried that. Below are the modified files.

Controller

class HomeController < ApplicationController
 def index
  registered_products = Product.where(product_type: 0).to_a
  unregistered_products = Product.where(product_type: 1).to_a

  @registered_products_array =  Kaminari.paginate_array(registered_products).page(params[:page]).per(10)
  @unregistered_products_array = Kaminari.paginate_array(unregistered_products).page(params[:page]).per(10)
 end
end

Every other relevant file is the same just substitute with the new global variables created. The problem still persists.

So my questions is how do I fix this problem and is it the problem occurring because I'm paginating the same object multiple times in the same page?


Solution

  • The reason why this problem is happening is because you are using the same params[:page] attribute to navigate through the pages. This results in the same number being passed to both the queries for your Product model. You will need to do this instead to get it working.

    Partial for registered page:

    ...
    <%= paginate @registered_products, param_name: :registered_page_no %>
    

    And in the unregistered page partial, you will have to do the same, but with a unique name like unregistered_page_no

    In your controller, all you need to do is this:

    class HomeController < ApplicationController
     def index
      @registered_products = Product.where(product_type: 0).page params[:registered_page_no]
      @unregistered_products = Product.where(product_type: 1).page params[:unregistered_page_no]
     end
    end 
    

    To know more about param_name, read the docs: https://github.com/kaminari/kaminari#changing-the-parameter-name-param_name-for-the-links