Dragos
Dragos

Reputation: 776

Rails update instance variable on ajax call to a method from the same controller

I have a view that is handled by a simple controller:

class CountController < ApplicationController

    def count
        @index = 0
    end
end

In my view I just added a button:

<%= link_to "Change next day", increase_count_path(@index), :class => 'btn' :remote => true %>

The request is being handled by a method I added in the CountController:

def increase_count
    @index = params[:index].to_i + 1
end

After trying it, I saw that each time the request is being sent to /increase_count/0 , so this obviously doesn't update the variable as I'd like it to.

So my guess is, the 2 are not linked. The first one has its scope in the view, and the second one, from the increase_count method is visible in whatever javascript I would render from it.

How can I achieve this in Rails? The thing I was trying to achieve and ran into this was the following (simplified version): I have an array of 3 Strings. Firstly I display the first one. On click I would like to make an Ajax call, increment the index, and display the next string. But I ended up showing only the second one, because the next calls don't update the index.

Upvotes: 2

Views: 1556

Answers (1)

Carlos Ramirez III
Carlos Ramirez III

Reputation: 7434

Your AJAX call will indeed update the @index instance variable within the controller, however if you don't re-render the link then it will continue to use the initial value of @index.

Consider re-rendering the link within a JavaScript template.

E.g.

// inside increase_count.js.erb

// Fetch the link in question and re-render it
// The newly rendered link will use the updated value from the instance variable within the #increase_count action

// Generates the link
// Use the j helper to escape any JavaScript within the text
var link = "<%= j link_to("Change next day", increase_count_path(@index), :class => 'btn' :remote => true) %>";

// Select the link using jQuery and update it
$("...").html(link);

You may want to turn the link into a partial to avoid duplicating the code in the view and in the JS template. You'll also want to use a good selector to grab the link more easily.

Upvotes: 5

Related Questions