Pagination in Rails - Always redirects to 1st page after edit/update an element belonging to the other pages
Asked Answered
E

8

5

I have used will_paginate gem for paginating index page of my test_app. It just shows the auctions listed and corresponding to each auction there is Edit, Destroy functionalities. My pagination is working good. I have 6 auctions in total listed in a table manner and as I put per_page = 2, 3 pages are there. But when I edit & Update the Auction in page 2 or 3, it just goes to 1st page after update action. I want that to stay on the same page.

My View - Index.html.erb

<h1>Listing auctions</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Category</th>
    <th>Item</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @auctions.each do |auction| %>
  <tr>
    <td><%= auction.name %></td>
    <td><%= auction.category %></td>
    <td><%= auction.item_id %></td>
    <td><%= link_to 'Show', auction %></td>
    <td><%= link_to 'Edit', edit_auction_path(auction) %></td>
    <td><%= link_to 'Destroy', auction, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />
<%= will_paginate @auctions %>
<%= link_to 'New Auction', new_auction_path %>
<%= link_to 'Back to Home', home_path %>

My Model - Auction.rb

class Auction < ActiveRecord::Base
  attr_accessible :name, :category, :item_id
  self.per_page = 2
end

My Controller - auctions_controller.rb

class AuctionsController < ApplicationController
  # GET /auctions
  # GET /auctions.json
  def index
    @auctions = Auction.paginate(:page => params[:page])#pagination for Index
    #@posts = Post.paginate(:page => params[:page])
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @auctions }
    end
  end

  # GET /auctions/1
  # GET /auctions/1.json
  def show
    @auction = Auction.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @auction }
    end
  end

  # GET /auctions/new
  # GET /auctions/new.json
  def new
    @auction = Auction.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @auction }
    end
  end

  # GET /auctions/1/edit
  def edit
    @auction = Auction.find(params[:id])
  end

  # POST /auctions
  # POST /auctions.json
  def create
    @auction = Auction.new(params[:auction])

    respond_to do |format|
      if @auction.save
        format.html { redirect_to @auction, notice: 'Auction was successfully created.' }
        format.json { render json: @auction, status: :created, location: @auction }
      else
        format.html { render action: "new" }
        format.json { render json: @auction.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /auctions/1
  # PUT /auctions/1.json
  def update
    @auction = Auction.find(params[:id])

    respond_to do |format|
      if @auction.update_attributes(params[:auction])
        format.html { redirect_to @auction, notice: 'Auction was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @auction.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /auctions/1
  # DELETE /auctions/1.json
  def destroy
    @auction = Auction.find(params[:id])
    @auction.destroy

    respond_to do |format|
      format.html { redirect_to auctions_url }
      format.json { head :no_content }
    end
  end
end

enter image description here

Please suggest a solution. Thank you.

Eriha answered 28/12, 2012 at 4:25 Comment(1)
Don't put urgent in your titlesFlavone
C
2

In your update action, you have the auction id, there you can calculate the expected page no. accordingly and use redirect_to @auction,:page=>page_no

or otherwise you would have to send the page parameter to the edit page from the show(when edit link is clicked) and then to the update action to use that page no to redirect

Chelonian answered 28/12, 2012 at 5:42 Comment(2)
How we can send the page_no from show to edit? can we use instance variable?Eriha
For that you would have to modify link of edit buttons and add pageno to it as edit_auction_path(auction,:page=>pageno)Chelonian
H
3

You need to retain params[:page] throughout edit/update operations and merge it with your query string

Heshum answered 28/12, 2012 at 5:45 Comment(2)
e.g. redirect_to @auction,:page => params[:page]Heshum
Where I need to specify that? I am using resourceful routing.Eriha
C
2

In your update action, you have the auction id, there you can calculate the expected page no. accordingly and use redirect_to @auction,:page=>page_no

or otherwise you would have to send the page parameter to the edit page from the show(when edit link is clicked) and then to the update action to use that page no to redirect

Chelonian answered 28/12, 2012 at 5:42 Comment(2)
How we can send the page_no from show to edit? can we use instance variable?Eriha
For that you would have to modify link of edit buttons and add pageno to it as edit_auction_path(auction,:page=>pageno)Chelonian
C
2

Here is my solution:

  1. In your index page which has edit/update button (add params page)

    = link_to content_tag(:span, "", :class => "fa fa-edit") + t('btn.edit'), edit_bill_path(bill, page: params[:page] || 1), :class => "btn btn-warning"
    
  2. In you form (add hidden field page)

    = f.input :page, as: :hidden, input_html: {value: params[:page]}
    
  3. In your controller (custom redirect path with page params)

    redirect_to your_path(page: params[:your_form_name_instance][:page]), notice: t('messages.update')
    
  4. Enjoy :)

Carotid answered 19/8, 2017 at 4:58 Comment(0)
B
1

This is what your delete method should look like in auctions_controller.rb if you want to just use :back for the redirect:

   # DELETE /auctions/1
   # DELETE /auctions/1.json
   def destroy
     @auction.destroy
     respond_to do |format|
       format.html { redirect_to :back }
       format.json { head :no_content }
     end
   end
Bondmaid answered 14/2, 2014 at 17:44 Comment(0)
S
0

You can use method total_pages on instance variable which you are using for pagination.

you can refer my answer for details

Segalman answered 8/7, 2013 at 7:58 Comment(0)
C
0

I used { redirect_to :back } and it maintained the same page.

Chinook answered 4/10, 2013 at 13:28 Comment(0)
C
0

Late answer but you can check for request.referrer if its available before showing redirecting to the deafault url using something like this in your edit, update or destroy actions:

  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to (request.referrer || posts_url), notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

You can also read how devise gem handles redirection in this file here

Credits answered 22/6, 2016 at 15:8 Comment(0)
P
0

I found the best way to do this is utilize redirect_back in Rails 5+.

Example:

# DELETE /guests/1
# DELETE /guests/1.json
def destroy
  @guest.destroy
  respond_to do |format|
    format.html { redirect_back(fallback_location: guests_url, notice: 'Guest was successfully destroyed.') }
    format.json { head :no_content }
  end
end

Basically it redirects to the referrer that referred to the destroy action. If there is no referrer fallback_location is used. For instance I have single button form on my index page that lists guests, and when the destroy button is clicked I am redirected back to the page where the guests are listed, the page param included!

Pacifa answered 23/10, 2017 at 20:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.