Taylor
Taylor

Reputation: 177

Following Feature From Michael Hartl's Rails Tutorial

I am trying to implement the follower feature from Hartl's RoR tutorial, chapter 12.

I have the feature working in that I can login, go to another user profile, click follow and (after refreshing the page) I see I am now following them. Same with unfollowing.

However, my integration tests fail, the Ajax doesn't work, and I get this error in my Rails server log when I click follow or unfollow:

Rendered users/_follow.html.erb (1.7ms)
Rendered relationships/destroy.js.erb (2.5ms)
Completed 500 Internal Server Error in 17ms
NoMethodError - undefined method `id' for nil:NilClass:

My code matches Hartl's exactly (I think). However, I am using FriendlyID on my User model and Devise, one of which (likely FriendlyID) is causing problems.

I believe this is all the relevant code.

Any ideas would be much appreciated... now on hour 5 or so of this!

controllers/users_controller.rb

def following
@title = "Following"
@user  = User.friendly.find(params[:id])
@users = @user.following
render 'show_follow'
end

def followers
@title = "Followers"
@user  = User.friendly.find(params[:id])
@users = @user.followers
render 'show_follow'
end

controllers/relationships_controller.rb

def create
user = User.friendly.find(params[: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

models/user.rb

# follows a user
def follow(other_user)
active_relationships.create(followed_id: other_user.id)
end

# unfollows a user
def unfollow(other_user)
  active_relationships.find_by(followed_id: other_user.id).destroy
end

# returns true if user is following the other user
def following?(other_user)
following.include?(other_user)
end

_unfollow.html.erb

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

_follow.html.erb

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

Upvotes: 1

Views: 869

Answers (1)

Jordan Allan
Jordan Allan

Reputation: 4486

In your relationships_controller.rb you haven't defined the @user variable, which is why you're receiving the undefined method error. Try this:

def create
  @user = User.friendly.find(params[: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

Upvotes: 5

Related Questions