ユーザー同士がフォローし合う機能を実装していきます。今回実装する部分のテーブル設計はこんな感じになります。Relationshipsテーブルは中間テーブルの役割を担っています。user_idfollower_idはどちらも外部キーです。

user_idUsersテーブルというのは理解できたのですが、follower_idとは??Followersテーブルなんて作ってないのですが、ある設定をRelationshipsテーブルを作るときにすると、followerを探すときはUsersテーブルのfollower_idをみるようになります。以下で説明していきます。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/277b029d-793e-41c8-9ec4-3bf7114ebd9a/_2021-06-01_14.41.05.png

Relationshipモデルを作成する

まず最初にRelationshipモデルを作成します。

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

外部キーのuser_idカラムとfollower_idカラムを作成します。ここでuser_idはフォローする人、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

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

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

Relationshipsテーブル作成完了です。

Sayo-MacBook-Pro:emoji_diary SAYO$ bundle exec rails db:migrate
== 20210601055359 CreateRelationships: migrating ==============================
-- create_table(:relationships)
   -> 0.2411s
== 20210601055359 CreateRelationships: migrated (0.2412s) =====================

UsersテーブルとRelationshipsテーブルのアソシエーションは複雑なので、フォローする、フォローされるの二つの状況に分けて定義していこうと思います。

フォローするアソシエーションを作成する

Userモデルのアソシエーションの記述は下記のようになります。