Search code examples
ruby-on-railsajaxruby-on-rails-4http-redirectlink-to

Rails 4: setup custom redirect_to in link_to helper with remote: true


In my Rails 4 app, I have a calendar and a post models: a calendar has_many posts and a post belong_to a calendar.

In Calendars#Show, I display all the posts that belong to this calendar.

In this very same view, I use the following link to update the approval custom attribute of a post:

<%= link_to post_path(:id => @post.id, "post[approval]" => "ok"), :method => :patch %>

Problem, once I click this link, I am taken to the Posts#Show view of this post.

What I would like instead, is to remain on the same Calendars#Show view.

I thought of implementing a redirect_to :back in my Posts#Update action in the controller, but this is not possible, since this would redirect me to the Posts#Edit view when I update a post from this very same Posts#Edit view.

So, I am looking for a solution to implement a redirect_to specifically for my link_to helper with remote: true from the Calendars#Show to the Calendars#Show.

Is that possible?


Solution

  • with remote: true

    If you're using remote (your code snippet does not have it), you won't be redirected anyway:

    <%= link_to post_path(:id => @post.id, "post[approval]" => "ok"), :method => :patch, remote :true %>
    

    The remote: true functionality invokes ajax, which is an XML call (through JS) to your server. By virtue of the call being out of "scope" (IE not a standard "request"), it will not cause any changes to your current browser state, unless you trigger them yourself:

    #app/controllers/posts_controller.rb
    class PostsController < ApplicationController
       def update
          @post = Post.find params[:id]
          respond_to do |format|
             if @post.update
               format.json #-> fired only when json is datatype
               format.js #-> invokes app/views/posts/update.js.erb
               format.html { redirect_to @post } #-> only fires on http request
             end
          end
       end
    end
    
    #app/views/posts/update.js.erb
    ## do what you want here
    

    from the Calendars#Show to the Calendars#Show

    If you want to refresh your page, you could use:

    #app/views/posts/update.js.erb
    window.location.reload(true);
    

    --

    To give you some more context, ajax stands for asynrhconous javascript and xml. This means that each of the requests you send with it are considered to be asynchronous -- or out of scope of the "normal" HTTP request.

    enter image description here

    Ajax requests are meant to be used to apply changes / updates to an already loaded page. A good example would be a chat system or something.

    Your question of how to redirect after an Ajax response, although not wrong, is definitely against convention of how it's considered to work. If you wanted to create a redirect as you are attempting to, I would highly recommend using a standard HTTP request with some conditions in your action:

    #app/controllers/posts_controller.rb
    class PostsController < ApplicationController
       def update
           @post = Post.find params[:id]
           @post.update post_params
           redirect_to posts_path if @post.approved.changed?
           redirect_to root_path if ....
       end
    end