【Rails】中間テーブルで2つのidの組み合わせ重複したとき無効にするテストを書く

バリデーションを書く

validates :user_id, :uniqueness => {:scope => :book_id}

一応migrationファイルにもt.indexを使ってDB側で同じ組み合わせが重複しないようにはしているけど、バリデーションとしてエラーを出せるように書いてみた。

こうすることで同じ組み合わせが重複するのを防ぐことができる。

テストを書く

it "user_idとbook_idの組み合わせが重複しているときは無効であること" do
    user = FactoryBot.create(:user)
    book = FactoryBot.create(:book)
    FactoryBot.create(
      :favorite,
      user: user,
      book: book
    )
    other_favorite = FactoryBot.build(
      :favorite,
      user: user,
      book: book
    )
    other_favorite.valid?
    expect(other_favorite.errors[:user_id]).to include 'はすでに存在します'
  end

まずuserとbookをFactoryBotを用いて作成する。

その後、中間テーブルであるfavoriteを呼び出し、作成したuserとbookを指定。

重複するものとしてother_favoriteに同じ内容を記述。

other_favorite.valid?とし、バリデーションを確かめる。

最初に書いたバリデーションが有効に働いていると「はすでに存在します」という文字列がincludeを使うことで引っかかるので、それをexpectする。

以上の書き方で重複する組合わせをテストすることができました。