Skip to content

Commit 43a6098

Browse files
committed
Add user following
1 parent d42ea79 commit 43a6098

25 files changed

+387
-7
lines changed

app/assets/stylesheets/application.bootstrap.scss

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,41 @@ aside {
134134
.gravatar_edit {
135135
margin-top: 15px;
136136
}
137+
.stats {
138+
overflow: auto;
139+
margin-top: 0;
140+
padding: 0;
141+
a {
142+
float: left;
143+
padding: 0 10px;
144+
border-left: 1px solid $gray-500;
145+
color: gray;
146+
&:first-child {
147+
padding-left: 0;
148+
border: 0;
149+
}
150+
&:hover {
151+
text-decoration: none;
152+
color: blue;
153+
}
154+
}
155+
strong {
156+
display: block;
157+
}
158+
}
159+
.user_avatars {
160+
overflow: auto;
161+
margin-top: 10px;
162+
}
163+
.gravatar {
164+
margin: 1px 1px;
165+
}
166+
a {
167+
padding: 0;
168+
}
169+
.users.follow {
170+
padding: 0;
171+
}
137172
/* forms */
138173
input,
139174
textarea,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class RelationshipsController < ApplicationController
2+
before_action :logged_in_user
3+
4+
def create
5+
@user = User.find(params[:followed_id])
6+
current_user.follow(@user)
7+
respond_to do |format|
8+
format.html { redirect_to @user }
9+
format.turbo_stream
10+
end
11+
end
12+
13+
def destroy
14+
@user = Relationship.find(params[:id]).followed
15+
current_user.unfollow(@user)
16+
respond_to do |format|
17+
format.html { redirect_to @user, status: :see_other }
18+
format.turbo_stream
19+
end
20+
end
21+
end

app/controllers/users_controller.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class UsersController < ApplicationController
2-
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
2+
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
3+
:following, :followers]
34
before_action :correct_user, only: [:edit, :update]
45
before_action :admin_user, only: :destroy
56

@@ -36,7 +37,6 @@ def update
3637
end
3738
end
3839

39-
4040
def index
4141
@users = User.paginate(page: params[:page])
4242
end
@@ -47,6 +47,20 @@ def destroy
4747
redirect_to users_url, status: :see_other
4848
end
4949

50+
def following
51+
@title = "Following"
52+
@user = User.find(params[:id])
53+
@users = @user.following.paginate(page: params[:page])
54+
render "show_follow", status: :unprocessable_entity
55+
end
56+
57+
def followers
58+
@title = "Followers"
59+
@user = User.find(params[:id])
60+
@users = @user.followers.paginate(page: params[:page])
61+
render "show_follow", status: :unprocessable_entity
62+
end
63+
5064
private
5165

5266
def user_params
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module RelationshipsHelper
2+
end

app/models/relationship.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Relationship < ApplicationRecord
2+
belongs_to :follower, class_name: "User"
3+
belongs_to :followed, class_name: "User"
4+
validates :follower_id, presence: true
5+
validates :followed_id, presence: true
6+
end

app/models/user.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
class User < ApplicationRecord
22
has_many :microposts, dependent: :destroy
3+
has_many :active_relationships, class_name: "Relationship",
4+
foreign_key: "follower_id",
5+
dependent: :destroy
6+
has_many :passive_relationships, class_name: "Relationship",
7+
foreign_key: "followed_id",
8+
dependent: :destroy
9+
has_many :following, through: :active_relationships, source: :followed
10+
has_many :followers, through: :passive_relationships, source: :follower
311
attr_accessor :remember_token, :activation_token, :reset_token
412
before_save :downcase_email
513
before_create :create_activation_digest
@@ -73,8 +81,28 @@ def password_reset_expired?
7381
reset_sent_at < 2.hours.ago
7482
end
7583

84+
# Returns a user's status feed.
7685
def feed
77-
Micropost.where("user_id = ?", id)
86+
following_ids = "SELECT followed_id FROM relationships
87+
WHERE follower_id = :user_id"
88+
Micropost.where("user_id IN (#{following_ids})
89+
OR user_id = :user_id", user_id: id)
90+
.includes(:user, image_attachment: :blob)
91+
end
92+
93+
# Follows a user.
94+
def follow(other_user)
95+
following << other_user unless self == other_user
96+
end
97+
98+
# Unfollows a user.
99+
def unfollow(other_user)
100+
following.delete(other_user)
101+
end
102+
103+
# Returns true if the current user is following the other user.
104+
def following?(other_user)
105+
following.include?(other_user)
78106
end
79107

80108
private
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<%= turbo_stream.update "follow_form" do %>
2+
<%= render partial: "users/unfollow" %>
3+
<% end %>
4+
<%= turbo_stream.update "followers" do %>
5+
<%= @user.followers.count %>
6+
<% end %>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<%= turbo_stream.update "follow_form" do %>
2+
<%= render partial: "users/follow" %>
3+
<% end %>
4+
<%= turbo_stream.update "followers" do %>
5+
<%= @user.followers.count %>
6+
<% end %>

app/views/shared/_stats.html.erb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<% @user ||= current_user %>
2+
<div class="stats">
3+
<a href="<%= following_user_path(@user) %>">
4+
<strong id="following" class="stat">
5+
<%= @user.following.count %>
6+
</strong>
7+
following
8+
</a>
9+
<a href="<%= followers_user_path(@user) %>">
10+
<strong id="followers" class="stat">
11+
<%= @user.followers.count %>
12+
</strong>
13+
followers
14+
</a>
15+
</div>

app/views/static_pages/home.html.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<section class="user_info">
55
<%= render 'shared/user_info' %>
66
</section>
7+
<section class="stats">
8+
<%= render 'shared/stats' %>
9+
</section>
710
<section class="micropost_form">
811
<%= render 'shared/micropost_form' %>
912
</section>

0 commit comments

Comments
 (0)