#前説
フォロー、フォロワー機能を実装しました。
イメージとしてはデータベースのテーブル関係とはどうするんだろうとかと、ハードル高そうに感じていました。
しかしgemを用いると結構すぐに実装できました。
#実装
- 非同期でフォロー、フォロワー機能を実装
#コード
以下のgemを導入します。
gem 'acts_as_follower'
follow_users POST /users/:id/follow(.:format) users#follow
unfollow_users POST /users/:id/unfollow(.:format) users#unfollow
導入部に関してはこちらを参考にして頂けた方がわかりやすいかと思います。
気になっていたデータベースとつなぐmodelの部分。
model/follow.rb
class Follow < ActiveRecord::Base
extend ActsAsFollower::FollowerLib
extend ActsAsFollower::FollowScopes
# NOTE: Follows belong to the "followable" interface, and also to followers
belongs_to :followable, :polymorphic => true
belongs_to :follower, :polymorphic => true
def block!
self.update_attribute(:blocked, true)
end
end
ここで知らないデータベース関連がでてきました。
polymorphic => true
followerとfollowableの二つの情報があるのに対し、用意されているテーブルは一つだけ。
つまり、フォローもフォロワーも親クラスから見た操作や情報がほとんど同じである為、一つのテーブルにまとめてしまおうというものらしい。
https://shirusu-ni-tarazu.hatenablog.jp/entry/2012/11/04/173742
↑参考記事
model/user.rb
class User < ApplicationRecord
acts_as_followable # フォロワー機能
acts_as_follower # フォロー機能
end
cotroller/user_controller.rb
def follow
@user = User.find(params[:id])
#ログイン中のユーザーで対象のユーザー(@user)をフォローする
current_user.follow(@user)
end
def unfollow
@user = User.find(params[:id])
#ログイン中のユーザーで対象のユーザー(@user)をフォロー解除する
current_user.stop_following(@user)
end
user/show.html.erb
<li id="user-<%= @user.id %>" class="collection-item">
<%= render 'users/follow', user: @user %>
</li>
user/_follow.html.erb
#任意のユーザーのマイページにて
#マイページのユーザーが現在ログインしているユーザーでない時->フォロー/フォロワーボタンを設置
<% if user.id != current_user.id %>
<li class="collection-item">
#現在のユーザーが対象のユーザーをフォローしてない時->「フォローするボタン」を設置
<% unless current_user.following?(user) %>
<div class="action">
<%= link_to 'フォローする' ,follow_users_path,method: :post, class: "btn waves-effect waves-light" ,remote: true %>
</div>
#現在のユーザーが対象のユーザーをフォローしてる時->「フォロー解除ボタン」を設置
<% else %>
<div class="action">
<%= link_to 'フォローを解除する' ,unfollow_users_path, method: :post,class: "btn waves-effect waves-light",remote: true %>
</div>
<% end %>
</li>
<% end %>
follow.js.erb
$("#user-<%= @user.id %>").html("<%= j(render partial: 'users/follow', locals: { user: @user }) %>")
unfollow.js.erb
$("#user-<%= @user.id %>").html("<%= j(render partial: 'users/follow', locals: { user: @user }) %>")
#結果
フォローするでしょ
#終わりに
感じたこととしてはいいね機能の実装と近い感じがしました。
#今後の実装
- フォロワーの数を数えてランキングにもしたい
- フォローしているユーザーによるタイムラインの実装とか