LoginSignup
2
1

More than 1 year has passed since last update.

フォロー・フォロワー機能

Posted at

1. Relationshipモデルを作成

$ rails g model Relationship follower_id:integer followed_id:integer
# follower_id:フォローするユーザーのid, followed_id:フォローされるユーザーのid
$ rails db:migrate
# マイグレーション実行

2. アソシエーションを記述

app/models/relationship.rb
class Relationship < ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
  # class_name: "User"を定義することでUserテーブルのレコードを参照する
end

補足説明:belongs_to :followerでfollowerテーブルのfollower_idを探しにいきます。
ただ、今回はfollowerテーブルは作成していないのと、
参照してもらいたいのはfollower_idに格納されている値と同じuser_idなので
class_name: "User"でUserテーブルを参照するように定義します。

3. Userモデルにメソッドを記述

app/models/user.rb
class User < ApplicationRecord
def follow(user_id)
    relationships.create(followed_id: user_id)/1
end

def unfollow(user_id)
    relationships.find_by(followed_id: user_id).destroy/2
 end

  def following?(user)
    followings.include?(user)/3
  end
end

1.followed_idがuser_idであるRelationshipsモデルを生成して保存します。
2.followed_idがuser_idであるRelationshipsモデルを取得してActiveRecordを使って削除します。
3.userが、Followingsモデルの中に含まれているか判定します。

app/models/user.rb
class User < ApplicationRecord
  has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy
  has_many :followers, through: :reverse_of_relationships, source: :follower
  # 被フォロー関係を通じて参照→followed_idをフォローしている人

  has_many :relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
  # 【class_name: "Relationship"】は省略可能
  has_many :followings, through: :relationships, source: :followed
  # 与フォロー関係を通じて参照→follower_idをフォローしている人
end

4. Relationshipコントローラを作成・編集

まずはrelationshipsコントローラを作成します。

$ rails g controller relationships
relationships_controller.rb
class RelationshipsController < ApplicationController
  before_action :authenticate_user
  def create
    following = @current_user.follow(params[:user_id])/1
    flash[:notice] = if following.save
                       'ユーザーをフォローしました'
                     else
                       'ユーザーのフォローに失敗しました'
                     end
    redirect_to("/users/#{params[:user_id]}")
  end

  def destroy
    following = @current_user.unfollow(params[:user_id])/2
    flash[:notice] = if following.destroy
                       'ユーザーのフォローを解除しました'
                     else
                       'ユーザーのフォロー解除に失敗しました'
                     end
    redirect_to("/users/#{params[:user_id]}")
  end

  def followings
    user = User.find(params[:user_id])/3
    @users = user.followings/4
  end

  def followers
    user = User.find(params[:user_id])/3
    @users = user.followers/4
  end

1.relationshipsコントローラーのcreateアクションにおいては、先程userモデルで定義したfollowメソッドを使っています。
2.relationshipsコントローラーのdestroyアクションにおいて、先程userモデルで定義したunfollowメソッドを使っています。
3.user = User.find(params[:user_id])で取得したユーザーのidが、
フォローしている もしくは フォローされている ユーザーのid一覧を
取得することができます。
4.@users = user.followings、
@users = user.followersでは、
先程userモデルで定義したアソシエーションを利用します。

引用記事

【Ruby on Rails】フォロー・フォロワー機能の実装
Railsでフォロー機能を作る方法

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1