Reputation: 3100
I implemented a "follow" feature from Michael Hartl's Rails tutorial. It worked fine for months but now all of a sudden the button no longer updates once it quits. I don't get any Javascript errors, nor do I get any errors in the Rails console. Clicking on the button will successfully create/destroy the "relationship". I only get an error in the Rails console when I try to click on the button again because it's trying to redo the transaction.
I do precompile my assets but this was never a problem. I had always precompiled my assets and pushed the app to Heroku and the button worked fine. The only change I implemented recently was the addition of the simple_form and haml-rails gems in order to get the mailboxer gem working right. I'm not sure if they are related but I figured that may help debug.
How did this break and how can I fix it? THANKS!
Relevant code:
Controller:
class RelationshipsController < ApplicationController
def create
@user = User.find(params[:relationship][:followed_id])
current_user.follow!(@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)
respond_to do |format|
format.html { redirect_to @user }
format.js
end
end
end
follow form
<% unless current_user == @user %>
<% if current_user.following?(@user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
follow
<%= 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-primary btn-small" %>
<% end %>
unfollow
<%= form_for(current_user.relationships.find_by_followed_id(@user),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-primary btn-small" %>
<% end %>
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 %>')
application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//= require bootstrap
//= require jquery
//= require jquery-ui
//= require jquery.tokeninput
//= require_tree .
I used to have //= require jquery_ujs
in the application.js but I had to remove it because clicking on the Follow button would cause the click to occur twice. Removing that line solved that problem, but the Ajax just doesn't seem to be updating the button anymore and I can't figure out why.
EDIT:
Rails console does show that the request is being received. I can even refresh the page and then the button will update:
Started DELETE "/relationships/32" for 127.0.0.1 at 2014-01-13 21:35:37 -0500
Processing by RelationshipsController#destroy as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"---edited---", "commit"=>"Unfollow", "id"=>"32"}
Relationship Load (0.4ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."id" = $1 LIMIT 1 [["id", "32"]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Relationship Load (0.4ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."follower_id" = 1 AND "relationships"."followed_id" = 2 LIMIT 1
(0.1ms) BEGIN
SQL (0.3ms) DELETE FROM "relationships" WHERE "relationships"."id" = $1 [["id", 32]]
(1.5ms) COMMIT
Rendered users/_follow.html.erb (2.5ms)
(0.7ms) SELECT COUNT(*) FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follower_id" WHERE "relationships"."followed_id" = 2
Rendered relationships/destroy.js.erb (6.0ms)
Completed 200 OK in 17.4ms (Views: 8.0ms | ActiveRecord: 4.2ms)
The Javascript console doesn't show any errors at all in Chrome.
EDIT 2 My network tab:
Upvotes: 0
Views: 574
Reputation: 3100
Found the issue. I was missing the <div id="follow_form">
on the follow form:
<% unless current_user == @user %>
<div id="follow_form">
<% if current_user.following?(@user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
Thanks everyone for your help!
Upvotes: 0
Reputation: 76774
If your create.js.erb
works (from your alert), the problem is going to be with the rendering of your JS
This is your current create.js.erb
:
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>")
$("#followers").html('<%= @user.followers.count %>')
#follow_form
still exist?users/unfollow
?#followers
exist?I think it's going to be a problem in your create.js.erb
. You can check this by clicking on right-click
-> inspect element
-> network
-> request you just sent
-- if there's an error, it will be red
Upvotes: 2
Reputation: 714
in Js console look up the Network tag and check the preview of ajax request to verify what respond the server, maybe the ids or class names are different
Upvotes: 0