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
各日記はたくさんのブックマークをもつことが出来ます。日記が消されるとブックマークも一緒に消えます。