Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialBrandon Hay
1,109 PointsMissing step in implementing AJAX
For everyone using Rails 4 for this tutorial you need to include the :remote => true attribute into your button. AJAX wouldn't work for me without this:
<%= link_to "Add Friend", new_user_friendship_path(friend_id: @user), id: 'add-friendship', data: { friend_id: @user.to_param }, class: 'btn btn-primary', :remote => true %>
Brandon Barrette
20,485 PointsWhat's the code in your view and your controller?
10 Answers
Brandon Barrette
20,485 PointsThe error is in the AJAX route. What I want you to do is go to your terminal and type:
rake routes
Then search in that list for the CREATE UserFriendship route. Check that against the route you see in the URL of the AJAX call.
You can also probably see this error if you open Google Chrome and go to View > Developer > Javascript Console. Click on the Console, you should see a red error after you click on the button.
oxanaox
16,295 PointsHi Brandon, thank you for helping out. I changed the route instead of user_friendship_path to user_friendships_path, I added "s" to friendships. But It stays the same, it still processes it as HTML when I press button "Add Friend".
Brandon Barrette
20,485 PointsSo there seems to also be an error in your create method:
@friend = User.find(params[:user_friendship][:friend_id])
This line doesn't make sense, I think you mean:
@friend = User.find_by(profile_name: params[:user_friendship][:friend_id])
Brandon Hay
1,109 PointsI think I can help on this one. Check out your gemfile. Do you have the turbolinks gem installed? If so, remove that from your gemfile and from any other files that reference it. I had this same exact problem and removing the turbolinks gem solved it for me.
Brandon Barrette
20,485 PointsI wouldn't remove turbolinks, instead do some research of how to make this work with turbolinks.
For example, instead of:
$(document).on("ready", function() {
\\this only fires when the page is initially loaded
});
try
$(document).on("page:change", function() {
\\this fires when the page is loaded every time by turbolinks
});
oxanaox
16,295 PointsBrandon, here are my user_friendships_controller.rb
class UserFriendshipsController < ApplicationController
before_filter :authenticate_user!
respond_to :html, :json
def index
@user_friendship = current_user.user_friendships.all
end
def accept
@user_friendship = current_user.user_friendships.find(params[:id])
if @user_friendship.accept!
flash[:notice] = "You are now friends"
else
flash[:error] = "That friendship can't be accepted."
end
redirect_to user_friendships_path
end
def new
if params[:friend_id]
@friend = User.where(profile_name: params[:friend_id]).first
raise ActiveRecord::RecordNotFound if @friend.nil?
@user_friendship = current_user.user_friendships.new(friend: @friend)
else
flash[:alert] = 'Friend Require'
end
rescue ActiveRecord::RecordNotFound
render file: 'public/404', status: :not_found
end
def create
if params[:user_friendship] && params[:user_friendship].has_key?(:friend_id)
#@friend = User.where(profile_name: params[:user_friendship][:friend_id]).first
@friend = User.find(params[:user_friendship][:friend_id])
@user_friendship = UserFriendship.request(current_user, @friend)
respond_to do |format|
if @user_friendship.new_record?
format.html do
flash[:error] ='There was a problem creating this friendship'
redirect_to profile_path(@friend)
end
format.json {render json: @user_friendship.to_json, status: :precondition_failed }
else
format.html do
flash[:notice] ='Friend request sent.'
redirect_to profile_path(@friend)
end
format.json {render json: @user_friendship.to_json }
end
end
else
flash[:error] = "Friend Required"
redirect_to root_path
end
def user_friendship_params
params.require(:user).permit(:user_id, :friend_id, :friend, :first_name, :profile_name, :user_friendship, :state)
end
end
def edit
@user_friendship = current_user.user_friendships.find(params[:id]).decorate
@friend = @user_friendship.friend
end
def destroy
@user_friendship = current_user.user_friendships.find(params[:id])
if @user_friendship.destroy
flash[:notice] ='Friendship destroyed.'
end
redirect_to user_friendships_path
end
end
```
oxanaox
16,295 PointsHere is show.html.erb
<div class="page-header">
<h1> <%= @user.profile_name %> </h1>
</div>
<% if signed_in? %>
<div id="friend-status">
<% if current_user.friends.include?(@user) %>
<%= link_to "Edit Friendship", edit_user_friendship_path(friend_id: @user), class: 'btn btn-success' %>
<% else %>
<%= link_to "Add Friend", new_user_friendship_path(friend_id: @user), class: 'btn btn-success', id: 'add-friendship', data: { friend_id: @user.to_param}%>
<% end %>
</div>
<% end %>
<% if @comments %>
<% @comments.each do |comment| %>
<div class="well">
<%= comment.body %>
<hr />
<%= link_to time_ago_in_words(comment.created_at), comment_path(comment) %> ago
</div>
<% end %>
<% end %>
oxanaox
16,295 PointsAnd here user_friendships.js
$(document).ready(function() {
$('#add-friendship').click(function(event) {
event.preventDefault();
var addFriendshipbtn = $(this);
$.ajax({
url: Routes.user_friendship_path({user_friendship: { friend_id: addFriendshipbtn.data('friendId') }}),
dataType: 'json',
type: 'POST',
success: function(e) {
addFriendshipbtn.hide();
$('#friend-status').html("<a href='#' class='btn btn-success'> Friendship Requested</a>");
}
});
});
});
oxanaox
16,295 PointsWhen I look at terminal it gives me: Started POST "/user_friendships" for 127.0.0.1 at 2014-11-02 08:30:20 -0800 Processing by UserFriendshipsController#create as HTML
So it's processes it as HTML and not as JS.
oxanaox
16,295 PointsBrandon, I followed the video tutorial and they had this line. I changed it for the line you suggested and I added :remote => true again because without it it would create it as html. I read in Rails documentation that remote command will trigger AJAX. So Now when I press button Add Friend nothing happens, however when I reload current page and press it again, it works. I tried like 5 times and when page loads nothing happens and "Add Friend" only works after reloading the page.
Brandon Barrette
20,485 PointsThe video tutorial was written for rails 3 and you are using rails 4. If you use the find method, it returns ALL instances, so you would have to call .first on that call. If you use find_by, it will automatically just take the first one called (this is new to rails 4)
You are having javascript issues is my guess.
oxanaox
16,295 PointsI deleted turbolinks, it works. Then after Brandon message advising not to delete turbo links, I added them back and changed js file and it works too. Thank you for your help! It works now.
Ben Wong
2,652 PointsTried deleting turbolinks, and adding this $(document).on("page:change", function() {
but no go:(
any other suggestions?
Ben Wong
2,652 PointsTried deleting turbolinks, and adding this $(document).on("page:change", function() {
but no go:(
any other suggestions?
Ben Wong
2,652 PointsGot it working. Have to remove user_friendship.coffee file and added :remote => true.
oxanaox
16,295 Pointsoxanaox
16,295 PointsI am stuck right now here and I use Rails 4. I added :remote => true, but it does not work with or without remote. Does anyone has the same issue? If I don't add :remote => true, it adds friends using html, but not json. If I add :remote => true, I see it tries to add it but looks at new method, not at create method. So, I'm stuck :(