I went through Treehouses tutorial on how to set up user friendships on adding and deleting friends. However, now I would like to show how many people that user is following and how many people are following that user. Michael Hartl's RoR tutorial goes over this however, I do not know how to implement his tutorial with Treehouses set up. I am a beginner and I know my controller is incorrect when referencing the users count. I am getting a NoMethodError undefined method `followers_count' in users/show.
Does anyone or has anyone succeeded in doing this? If so any pointers on where to go and look or how I can do this would be greatly appreciated! Thanks.
User / Model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts
has_many :user_friendships
has_many :friends, through: :user_friendships,
conditions: { user_friendships: { state: 'accepted'} }
has_many :pending_user_friendships, class_name: 'UserFriendship',
foreign_key: :user_id,
conditions: { state: 'pending' }
has_many :pending_friends, through: :pending_user_friendships, source: :friend
has_many :requested_user_friendships, class_name: 'UserFriendship',
foreign_key: :user_id,
conditions: { state: 'requested' }
has_many :requested_friends, through: :pending_user_friendships, source: :friend
has_many :blocked_user_friendships, class_name: 'UserFriendship',
foreign_key: :user_id,
conditions: { state: 'blocked' }
has_many :blocked_friends, through: :pending_user_friendships, source: :friend
has_many :accepted_user_friendships, class_name: 'UserFriendship',
foreign_key: :user_id,
conditions: { state: 'accepted' }
has_many :accepted_friends, through: :pending_user_friendships, source: :friend
validates :name, presence: true
has_one :profile
belongs_to :user
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "150x150>" }, :default_url => "/assets/avatar.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
def has_blocked?(other_user)
blocked_friends.include?(other_user)
end
def followers_count
user_friendships.count
end
def followed_by_count
UserFriendship.where(friend_id: self.id).count
end
end
User / Show. html
<% provide(:title, @user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= image_tag @user.avatar.url(:thumb) %>
<%= @user.name %>
<%= @user.followers_count%>
<%= @user.followed_by_count %>
</h1>
<div id="friend-status">
<% if current_user.friends.include?(@user) || current_user.pending_friends.include?(@user) %>
<%= link_to "Edit Friendship", edit_user_friendship_path(friend_id: @user), class: "btn btn- info btn-sm" %>
<% else %>
<%= link_to "Follow", new_user_friendship_path(friend_id: @user), class: "btn btn- info btn-sm", id: 'add-friendship', data: { friend_id: @user.to_param } %>
<% end %>
</div>
</section>
</aside>
</div>
User Friendship Controller
class UserFriendshipsController < ApplicationController
before_filter :authenticate_user!
respond_to :html, :json
def index
@user_Friendships = UserFriendshipDecorator.decorate_collection(friendship_association.all)
respond_with @user_Friendships
end
def accept
@user_friendship = current_user.user_friendships.find(params[:id])
if @user_friendship.accept_mutual_friendship!
@user_friendship.friend.user_friendships.find_by(friend_id: current_user.id).accept_mutual_friendship!
flash[:success] = "You are now friends with #{@user_friendship.friend.name}!"
redirect_to user_friendships_path
else
flash[:error] = "That friendship could not be accepted."
end
end
def block
@user_friendship = current_user.user_friendships.find(params[:id])
if @user_friendship.block!
flash[:success] = "You have blocked #{@user_friendship.friend.name}."
else
flash[:error] = "This friendship could not be blocked."
end
redirect_to user_friendships_path
end
def new
if params[:friend_id]
@friend = User.find(params[:friend_id]).first
raise ActiveRecord::RecordNotFound if @friend.nil?
@user_friendship = current_user.user_friendships.new(friend: @friend)
else
flash[:error] = "Friend required."
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.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 friend request."
redirect_to user_path(@friend)
end
format.json { render json: @user_friendship.to_json, status: :precondition_failed }
else
format.html do
flash[:success] = "Friend request sent."
redirect_to user_path(@friend)
end
format.json { render json: @user_friendship.to_json }
end
end
else
flash[:error] = "Friend required"
redirect_to root_path
end
end
def edit
@friend = User.find(params[:id])
@user_friendship = current_user.user_friendships.find_by(friend_id: @friend.id).decorate
end
def destroy
@user_friendship = current_user.user_friendships.find(params[:id])
if @user_friendship.destroy
flash[:success] = "Your friendship was deleted"
end
redirect_to user_friendships_path
end
def user_friendship
params.require(:user_friendship).permit(:user_id, :friend_id, :user, :friend, :state, :user_friendship)
end
def avatar
end
def followers_count
@user_friendship.find_by_follower_id(friend.id)
end
def followed_by_count
@user_friendship.create!(friend_id: friend.id)
end
private
def friendship_association
case params[:list]
when nil
current_user.user_friendships
when 'blocked'
current_user.blocked_user_friendships
when 'pending'
current_user.pending_user_friendships
when 'accepted'
current_user.accepted_user_friendships
when 'requested'
current_user.requested_user_friendships
end
end
end
It looks like you are mixing the User model methods with the relationship model methods. You are calling @user.followers_count
which is looking for the followers_count
method on user, which does not exist. You have it defined on the UsersFriendships
model. You didn't include the User
model, but it should look something like this to get rid of this error, though there may be a few more after you get past it.
class User < ActiveRecord::Base
has_many :user_friendships
#everything else
def followers_count
user_friendships.count
end
def followed_by_count
UserFriendship.where(friend_id: self.id).count
end
end
You will want to remove the followers_count
and followed_by_count
from the UserFriendship
model. Also, it looks like you have some private methods in the controller as well called followers_count
and followed_by_count
.