Bookmarkモデルは多対多の関係であるUserモデルとDiaryモデルの中間テーブルの役割を担います。今回作成するBookmarksテーブルのアソシエーションはこのようになっています。user_idとdiary_idを外部キーとして持っています。

まず最初にBookmarksモデルを作成します。
Sayo-MacBook-Pro:emoji_diary SAYO$ bundle exec rails generate model Bookmark user:references diary:references
Running via Spring preloader in process 39970
invoke active_record
create db/migrate/20210603130042_create_bookmarks.rb
create app/models/bookmark.rb
作成されたマイグレーションファイルに必要な制約を追加します。
class CreateBookmarks < ActiveRecord::Migration[6.1]
def change
create_table :bookmarks do |t|
t.references :user, null: false, foreign_key: true
t.references :diary, null: false, foreign_key: true
t.timestamps
end
add_index :bookmarks, [:user_id, :diary_id], unique: true
end
end
user_idとdiary_idのunique制約は、user_idとboard_idの組み合わせがuniqueであることを示しています。これはユーザーが同じ日記をお気に入り登録しないようにするためです。この設定が終わったらrails db:migrateを行います。
Sayo-MacBook-Pro:emoji_diary SAYO$ bundle exec rails db:migrate
== 20210603130042 CreateBookmarks: migrating ==================================
-- create_table(:bookmarks)
-> 0.3564s
-- add_index(:bookmarks, [:user_id, :diary_id], {:unique=>true})
-> 0.1609s
== 20210603130042 CreateBookmarks: migrated (0.5174s) =========================
データベースではuser_idとdiary_idにnull制約とunique制約をかけました。それを踏まえてモデルにバリデーションを追加していきます。
まず最初はBookamarkモデルです。belongs_toオプションを設定した場合に、対象カラムに対するpresence: trueは自動で設定されるので不要となります。user_idのバリデーションは、user_idに対して、diary_idはuniqueな関係であるということを意味しています。
class Bookmark < ApplicationRecord
belongs_to :user
belongs_to :diary
validates :user_id, uniqueness: { scope: :diary_id }
end
次に中間テーブルであるBookmarkモデルとUserモデル、Diaryモデルのアソシエーションを定義していきます。
まず最初にDiaryモデルにアソシエーションを追加します。
class Diary < ApplicationRecord
has_many :bookmarks, dependent: :destroy
end
各日記はたくさんのブックマークをもつことが出来ます。日記が消されるとブックマークも一緒に消えます。