Question

I can't get Ajax working in my Rails app.

With the magic of Ajax: When I click the "follow" button, it should update the number of followers the user sees in the profile page without having to refresh the page. However, this isn't happening for me in my sample app.

What is happening is that the "follow" button, when clicked, changes to "unfollow" as it should BUT, the number of followers stays the same until I hit the refresh button in the web-browser (tested in FF and IE). I'm following Michael Hartl's railstutorial.org, using Rails 4 and Ruby 2.0.0p195.

This is the console message I get from FireFox:

Empty string passed to getElementById().

This is my code below, the "follow" button in the view corresponds to actions in the relationships controller and they're supposed to hit the create.js.erb and destroy.js.erb partials.


-CONTROLLER- relationships_controller.rb

def create
    @user = User.find(params[:relationship][:followed_id])
    current_user.follow!(@user)
    # redirect_to @user
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end

def destroy
  @user = Relationship.find(params[:id]).followed
  current_user.unfollow!(@user)
  # redirect_to @user 
  respond_to do |format|
    format.html { redirect_to @user }
    format.js
  end
end

-JAVASCRIPT- _create.js.erb:

 $("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
 $("#followers").html('<%= @user.followers.count %>');

_destroy.js.erb:

 $("#follow_form").html("<%= escape_javascript(render('users/follow')) %>");
 $("#followers").html('<%= @user.followers.count %>');

-VIEWS- are follow_form, with _follow.html.erb and _unfollow.html.erb.

_follow_form.html.erb

 <% unless current_user?(@user) %>
 <div id="follow_form">
    <% if current_user.following?(@user) %>
        <%= render 'unfollow' %>
    <% else %>
        <%= render 'follow' %>
    <% end %>
 </div>
 <% end %>

_follow.html.erb:

 <%= form_for(current_user.relationships.build(followed_id: @user.id), remote: true) do |f| %>
    <div><%= f.hidden_field :followed_id %></div>
    <%= f.submit "Follow", class: "btn btn-large btn-primary" %>
 <% end %>

_unfollow.html.erb

<%= form_for(current_user.relationships.find_by(followed_id: @user), html: { method: :delete }, remote: true) do |f| %>
   <%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>

Note - I'm using postgreSQL on development instead of SQLlite that is used in the railstutorial.

EDIT in response: _stats.html.erb

 <% @user = @user || current_user %>

 <div class="stats">
    <a href="<%= following_user_path(@user) %>">
        <strong id="following" class="stat">
            <%= @user.followed_users.count %>
        </strong>
        following
    </a>

    <a href="<%= followers_user_path(@user) %>">
        <strong id="following" class="stat">
            <%= @user.followers.count %>
        </strong>
        followers
    </a>
 </div>
Was it helpful?

Solution

Because in your _stats.html.erb file, you dont have element with id followers. Please see your code

<a href="<%= followers_user_path(@user) %>">
    <strong id="following" class="stat">
        <%= @user.followers.count %>
    </strong>
    followers
</a>

It should be

<a href="<%= followers_user_path(@user) %>">
    <strong id="followers" class="stat">
        <%= @user.followers.count %>
    </strong>
    followers
</a>

OTHER TIPS

I'll post my fix. in my _follow_form.html.erb file I did not include the id="follow_form" because of my own styling. You need to be sure to include the follow_form ID.

it should be:

<% unless current_user?(@user) %>
  <div id="follow_form">
    <% if current_user.following?(@user) %>
      <%= render 'unfollow' %>
    <% else %>
      <%= render 'follow' %>
    <% end %>
  </div>
<% end %>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top