ポートフォリオで使用するために一度試しに実装してみたいと思います。フォローする、フォロー解除するボタンはAjaxを使って非同期通信にしたいです。事前にユーザー登録、ログインはsorceryで実装済みです。

参考にしたサイト

Railsでユーザーフォロー機能を実装する(Ajax使うよ)① - Qiita

テーブル設計

ユーザーフォロー機能の実装のために用意したテーブル設計は下記のようになります。本当に分かりづらいのですが、RelationshipsテーブルがUsersテーブル(フォローするユーザー)とUsersテーブル(フォローされるユーザー)の中間テーブルとしての役割を担っています。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/05df89e7-e8b2-46db-a1cf-a486dd321ce3/_2021-05-31_22.42.38.png

Relationshipモデルを作成する

まずはRealtionshipモデルを作成します。

Sayo-MacBook-Pro:migrate SAYO$ bundle exec rails g model Relationship
Running via Spring preloader in process 1766
      invoke  active_record
      create    db/migrate/20210531014628_create_relationships.rb
      create    app/models/relationship.rb

外部キーのuser_idカラムとfollower_idカラムを作成します。ここでuser_idはフォローする人、follower_idはフォローされる人を指します。

follower_idの参照先のテーブルはUsersテーブルにしてあげたいので、foreign_key: {to_table: :users}としてあげてます。この設定をしないと存在しないfollowerテーブルを参照しようとします。この設定をすることで、followerを探すときはUsersテーブルのfollower_idをみるようになります。

class CreateRelationships < ActiveRecord::Migration[6.1]
  def change
    create_table :relationships do |t|
      t.references :user
      t.references :follower, foreign_key: { to_table: :users }

      t.timestamps

      t.index [:user_id, :follower_id], unique: true
    end
  end
end

外部キー制約をつけたので、インデックスは自動で付与されるので、add_index :relationships, :follower_idという記載は不要です。

t.index [:user_id, :follower_id], unique: trueこの記載は、unique制約で同じ人を2回フォローできないようにするために必要です。

マイグレーションファイルの修正が終わったので、テーブルを作成します。

Sayo-MacBook-Pro:migrate SAYO$ rails db:migrate
== 20210531014628 CreateRelationships: migrating ==============================
-- create_table(:relationships)
   -> 0.1209s
== 20210531014628 CreateRelationships: migrated (0.1210s) =====================