whatsinahat
whatsinahat

Reputation: 41

Paginate many has_many belongs_to relationships in Rails with will_paginate

A user has_many potatoes. Potatoes belong_to a user. A potato has_many quirks. Quirks belong_to potatoes.

I want to display my potatoes and their associated quirks together in my Users show and Paginate using the will_paginate gem like below.

potato_names -> sweet potato    russet potato   mystery potato
quirk_name ->   shiny           rough           purple
quirk_name ->   big             brown           orange
quirk_name ->   old             medium          blue

My users controller pre-pagination

UsersController

  def show
    @user = User.find(params[:id])
    @potatoes = @user.potatoes
    @quirks = Quirk.where(potato: @potatoes)
  end

I can paginate potatoes by changing the UsersController -

@potatoes = @user.potatoes.paginate(page: params[:page])

and Users - show.html.erb

<%= @potatoes.potato_name %>
<%= will_paginate @potatoes %>

but how can I get quirks to paginate with the potatoes so that when I click next I get the potatoes and quirks associated with the next set? Initially I was getting potatoes to paginate and quirks to just show itself, which is why I didn't display quirks previously. I wasn't understanding the .pagination call well enough.

I can call :param_name to specify the parameter name for page number, and make sure that it's working appropriately.

will_paginate documentation

I can do

UsersController
  def show
    @user = User.find(params[:id])
    @potatoes = @user.potatoes.paginate(page: params[:potatoes_page])
    @quirks = Quirk.where(potato: @potatoes).paginate(page: params[:quirks_page])
  end

show.html.erb

<%= render @potatoes %>
<%= render @quirks %>

<%= will_paginate @potatoes, :params_name => 'potatoes_page' %>
<%= will_paginate @quirks, :params_name => 'quirks_page' %>

_potato.html.erb

 <%= potato.potato_name %>

_quirk.html.erb

 <%= quirk.quirk_name %>

This should give me potatoes and quirks paging separately... But when I next page potatoes, potatoes is paging and quirks is disappearing. When I next page quirks page, potatoes stays the same and only quirks changes.

I believe that the above error is because I'm calling pagination in the potatoes query, then using the potatoes query to call pagination again.

Upvotes: 3

Views: 869

Answers (1)

whatsinahat
whatsinahat

Reputation: 41

The overall look should be:

UsersController
  def show
    @user = User.find(params[:id])
    @potatoes = @user.potatoes.paginate(page: params[:page])
    @quirks = Quirk.where(potato: @user.potatoes).paginate(page: params[:page])
  end

show.html.erb

<%= render @potatoes %>
<%= render @quirks %>

<%= will_paginate @potatoes, :params_name => 'page' %>

_potato.html.erb

<%= potato.potato_name %>

_quirk.html.erb

<%= quirk.quirk_name %>

The error was in calling pagination on a pagination with @potatoes and @quirks in the UsersController. Additionally I changed :params_name back to the default page so both models would change at the same time. To change them separately, use potatoes_page and quirks_page as shown in the question. I also removed

<%= will_paginate @quirks %>

because I was getting two next bars. If you are changing @potatoes and @quirks separately, you would need to include it.

Upvotes: 1

Related Questions