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 trial

Ruby

How can I show the count of a users followers and who they are following like twitter or Instagram?

I went through Treehouses tutorial on how to set up user friendships with 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. 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. In case someone wanted to see my code I have added it.

User_Friendship / Model

 class UserFriendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, class_name: 'User', foreign_key:  'friend_id'

  after_destroy :delete_mutual_friendship!

  state_machine :state, initial: :pending do

    after_transition on: :accept, do: [:send_acceptance_email, :accept_mutual_friendship!]
    after_transition on: :block, do:  [:block_mutual_friendship!]    

    state :requested
    state :blocked

    event :accept do
        transition any => :accepted
    end

    event :block do
        transition any => :blocked
    end
   end

  validate :not_blocked


  def self.request(user1, user2)
    transaction do
        friendship1 = create(user: user1, friend: user2, state: 'pending')
        friendship2 = create(user: user2, friend: user1, state: 'requested')

        friendship1.send_request_email if !friendship1.new_record?
        friendship1
     end    
   end


  def not_blocked
   if UserFriendship.exists?(user_id: user_id, friend_id: friend_id, state: 'blocked') ||
      UserFriendship.exists?(user_id: friend_id, friend_id: user_id, state: 'blocked')
    errors.add(:base, "The friendship cannot be added.")
    end
   end

  def send_request_email
    UserNotifier.friend_requested(id).deliver
  end

  def send_acceptance_email
    UserNotifier.friend_request_accepted(id).deliver
  end

  def mutual_friendship
  self.class.where({user_id: friend_id, friend_id: user_id}).first
  end

  def accept_mutual_friendship!
# Grab the mutual friendship and update the state without  using the state machine, so as
 # not to invoke callbacks.
 mutual_friendship.update_attribute(:state, 'accepted')
 end 

 def delete_mutual_friendship!
 mutual_friendship.delete
 end

 def block_mutual_friendship!
    mutual_friendship.update_attribute(:state, 'blocked') if mutual_friendship
  end 
end

 def followers_count
  self.userFriendships.count 
 end

 def followed_by_count
  UserFriendship.where(:friend_id=> self.id).count 
 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>

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

1 Answer

im a novice, but for your user model I think i add two methods to check followers and following, since you set up the relation

def followers_count
     self.userFriendships.count
end

def followed_by_count
     UserFriendship.where(:friend_id=> self.id).count
end

Thanks Chris! This is definitely a start. What would I put in the view or controller in order to get the count to be displayed? I'm sorry I am a complete novice as well. Thanks again.

We'll that would be part of your user model , so assuming @user is the instance of a user you want to get count of you would just do <%= @user.followers_count%> or <%= @user.followed_by_count %>

Thanks!