16
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Mysql2::Error: Duplicate entry for key.. エラーを撃退した話 [Rails]

Last updated at Posted at 2018-12-03

はじめに

Railsでの開発でレコードに一意性制約を設けるにあたって、マイグレーションファイルに記述してスキーマに登録しました。
ですので、重複するレコードデータは自動的に保存されるときに弾かれるものと思い込んでいたために、 Mysql2::Error: Duplicate entry for key..というエラーに遭遇しました。
その解決策を備忘録として書き記します。

エラー公開

20181202104022_create_friends.rb
class CreateFriends < ActiveRecord::Migration[5.2]
  def change
    create_table :friends do |t|
      t.integer :from
      t.integer :to

      t.timestamps null: false
    end

    add_index :friends, :from
    add_index :friends, :to
    add_index :friends, [:from, :to], unique: true  
  end
end

上記のように、friendsテーブルにfromカラムとtoカラムの組み合わせが一意であるようにインデックスに登録しました。

問題発生

これでマイグレーションファイルを実行し、データを保存しようとしたところ、 Mysql2::Error: Duplicate entry for key..エラーに遭遇しました。

$ rake db:migrate
friends_controller.rb
  def add_friend
    @friend = Friend.new(from: ..., to: ...)
    @friend.save
    .
    .
    .
  end
  end

コードは端折っておりますが、上記のような感じです。一意性制約を設けたために、同じカラム値の組み合わせデータをsaveメソッドで保存しようとすると、エラーが発生しました。

解決

下記コード一行をfriendモデルに追記するとエラーは無くなりました。

friend.rb
class Friend < ApplicationRecord
  validates :from, uniqueness: { scope: :to }
end

スキーマに記すとともに、バリデーションの記述をモデルにも書く必要があったのですね。

ちなみに上記のコードは複数のフィールド(カラム)で一意になるようにチェックしたい時の記述になります。

エラー記事まとめ

*2018/12/04時点で、まだ2記事しかございません。これからストックしていきます。
みなさんが同様のエラーに遭遇した時の一助になると幸いです。

Mysql2::Error::ConnectionErrorの謎を解明!
undefined local variable or method display_meta_tags for..

終わりに

同じエラーに遭遇してこの記事が役にたったよー、って方はいいねしてくれると嬉しいです(^^)

16
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?