フォロー一覧、フォロワー一覧を実装する記事はよく見かけるのですが、相互フォロー一覧を取得する実装は見かけなかったので、今回記事にしました。
前提
基本的なフォロー・フォロワー機能がすでに実装してあることが前提となります。
具体的には以下のような実装を前提としています。
モデル
user.rb
class User < ApplicationRecord
has_many :relationships, class_name: 'Relationship',
foreign_key: 'follower_id',
dependent: :destroy,
inverse_of: :follower
has_many :reverse_of_relationships, class_name: 'Relationship',
foreign_key: 'followed_id',
dependent: :destroy,
inverse_of: :followed
has_many :followings, through: :relationships, source: :followed
has_many :followers, through: :reverse_of_relationships, source: :follower
def follow(other_user_id)
relationships.create!(followed_id: other_user_id)
end
def unfollow(other_user_id)
relationships.find_by(followed_id: other_user_id).destroy!
end
def following?(user)
followings.include?(user)
end
end
実装は、以下の記事を参考にしました。
[Rails]フォロー、フォロワー機能
相互フォロー一覧の取得
結論から書くと、以下の実装で相互フォロー一覧が取得できます。
user.rb
def mutual_followings
followings & followers
end
順番に見ていきましょう。
まずfollowings(followers)
とすることで、ユーザーに紐づくフォロー(フォロワー)一覧
を取得できます。
なぜならUserモデル
とRelationshipモデル
を関連付けをしているからです。
以下の部分です。
has_many :followings, through: :relationships, source: :followed
has_many :followers, through: :reverse_of_relationships, source: :follower
で、followings & followers
と書くことでどのような状態となっているかというと、
# followings のレスポンス & followers のレスポンス
[object, object, object] & [object, object, object]
このようになっています。
&
演算子を使うことで両方の配列に含まれる要素からなる新しい配列を返します。
例
[1, 1, 2, 3] & [3, 1, 4] #=> [1, 3]
Ruby3.2リファレンスマニュアルから引用
つまり、自分がフォローしている、かつ自分をフォローしてくれている(相互フォロー状態)のユーザー一覧を取得できるということです。