Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3: Links that Call Actions but Don't Leave/Refresh the Current Page?

Is there a way in Rails 3 to call an action (to play around with a database) without refreshing or running the action then redirecting to the current page?

I tried messing with :remote => true in link_to, but it doesn't work for me. Or maybe I misunderstood its purpose... or I'm using it incorrectly.

like image 227
Derek Avatar asked Oct 30 '11 09:10

Derek


2 Answers

There are 2 scenarios you normally have when calling an action from a view in Rails3:

  1. Using the normal link_to with its variations.
  2. Using link_to with the optional argument :remote => true (default is false)

The first one results in the the normal request / response cycle:

  1. Call the action in the controller.
  2. If there is nothing special done (render or redirect), just render the view that is related to the action. So if the action is called do_db_stuff, Rails3 tries to render do_db_stuff.html.erg (or do_db_stuff.html.haml`) in the relevant views directory.
  3. You may change that by calling explicitly render or redirect at the end of your action:
    • render: Renders the template you name, using the current state of the controller.
    • redirect: Redirect to a new action (of this or another controller), and using the relevant template to render then.

This is e.g. used when calling in the create action some save method, which fails, then you return to the same page by calling render :action => "new" # doen't execute the method

The second one just calls the action, and returns the result to the page. It is the responsibility of the page what to do with this. In a slightly different scenario, I have e.g. in my application something that goes like that:

  1. On the left side of the view, there is a list of tasks.
  2. To each task item, there is registered an on-click handler that calls search_task (by using JavaScript with AJAX) on the controller.
  3. The controller responds to that call by sending the result of a render :partial ... call back.
  4. The JavaScript function in the handler has registered a success function that looks like that:

    element.bind('click', function() {
        $('#left').children().removeClass('selected')
        element.addClass('selected');
        $.ajax({url: '/tasks/search_task/' + task_id, 
            async: false,
            dataType: 'html',
            success: function(data) {
                target.html(data);
            }});
    }
    

    (have appended the whole click-function here)

  5. So the result (when successful sent) will result that the contents of target will be replaced with the sent HTML code.

I don't know if something similar is possible with link_to, perhaps there is an option.

So yes, :remote => true should work for you if you only want to ignore the result.

like image 197
mliebelt Avatar answered Sep 28 '22 10:09

mliebelt


I am using AJAX request for this:

<%= link_to "stock", { :controller => 'ReadItLater', :action => "stock", 
                     :qid => q.question_id } , :remote => true, :class=>'ddm' %>

Here is a controller code:

    def stock
      @user = UserData.find_by_login(session[:cuser])
      @user.stock(params)

      respond_to do |format|
          format.js { render :layout=>false }
      end
  end
like image 28
ceth Avatar answered Sep 28 '22 12:09

ceth