前提
- deviseでユーザーに関する機能作成済み
- jqueryが使える環境を構築済み
概要
フォロー機能の仕組みについては、RailsTutorialに詳しく書かれているので、参照することをお勧めします。今回用いるカラム名やモデル名は以下の通りです。メモ程度ですが参考程度に載せておきます。
Relationshipモデルを作成
コンソールでrelationshipモデルを作成
rails g model relationships
- 参照
- フォロワー: userテーブルを参照する
- フォロー :
followという名前で
userテーブルを参照する - index
- user_idとfollow_idが一致することが無い様に、複合キーインデックスを追加
- これにより、「自分が自分をフォローする」ということを防げる
20210104064312_create_relationships.rb
class CreateRelationships < ActiveRecord::Migration[6.0]
def change
create_table :relationships do |t|
t.references :user, foreign_key: true
t.references :follow, foreign_key: { to_table: :users }
t.timestamps
t.index [:user_id, :follow_id], unique: true
end
end
end
マイグレーションを実行
rails db:migrate
relationshipモデルとuserモデルのリレーションは以下の通り記述する。
また、validationも記述。
relationship.rb
class Relationship < ApplicationRecord
belongs_to :user
belongs_to :follow, class_name: 'User'
validates :user_id, presence: true
validates :follow_id, presence: true
end
- 関連付けについては、上記画像を参照していただけると幸いです。
- 「フォローする」「フォローを外す」「フォローしているか確認」のメソッドは何度も使用するので、定義しておきます。
relationship.rb
class User < ApplicationRecord
has_many :relationships, dependent: :destroy
has_many :followings, through: :relationships, source: :follow
has_many :reverse_of_relationships, class_name: 'Relationship', foreign_key: 'follow_id', dependent: :destroy
has_many :followers, through: :reverse_of_relationships, source: :user
def follow(other_user_id)
relationships.find_or_create_by(follow_id: other_user_id) unless id == other_user_id.to_i
end
def unfollow(other_user_id)
relationship = relationships.find_by(follow_id: other_user_id)
relationship.destroy if relationship
end
def following?(other_user)
followings.include?(other_user)
end
end
view controllerの作成
- 自ユーザページの場合は、「編集ボタン」、他ユーザページの場合は、「フォローボタン」を表示する様にします。
app/views/users/show.html.erb
<div>
<% if @user.id == current_user.id %>
<%= link_to 'Edit', edit_user_registration_path(current_user) %>
<% else %>
<%= render partial: 'follow' %>
<%= render partial: 'follow_count'%>
<% end %>
</div>
app/views/users/_follow.html.erb
<span id="follow">
<%= follow_button(@user) %>
</span>
- follow_buttonを定義しています。
- Bootstrapを使用している方は、フォロー中かどうかに応じてkeyにprimaryかsecondaryが入るため、ボタンの色を変えることができます。(Bootstrap不使用の方は消してしまって問題ないです。)
-
remote: true
を入れることによって、Ajax通信をすることができます。
app/helpers/application_helper.html.erb
module ApplicationHelper
def follow_button(user)
label, key = current_user.following?(user) ? %w[フォロー中 secondary] : %w[フォローする primary]
link_to(label, user_follow_path(@user), method: :post, remote: true, class: "btn btn-#{key} rounded-pill")
end
end
- javascriptで書かれています。
-
html内のidがfollowの中身をrenderする
ことができます。
app/views/users/follow.js.erb
$('#follow').html('<%= j(render partial: "follow") %>');
- 忘れずにrouteも変えましょう。
- post通信を行うために指定が必要です。
routes.rb
Rails.application.routes.draw do
resources :users, only: %w[index show] do
post :follow
end
end
最後に
@user.followers.count
や@user.followings.count
で、フォロワー数やフォロー数をカウントして表示することが可能です。こちらの記事を理解することができていれば、簡単にAjaxで実装できるので、やってみてください。