データベースからロードする ActiveRecord オブジェクトがあります。
valid?
このオブジェクトを呼び出すfalse
と、レールの一意の制約が満たされていないために返されます。少なくとも検証ではそうです。
データベースのスキーマを確認したところ、一意のフィールドにもインデックスが定義されているため、データベース レベルでも一意性が保証されています。
ここで何が起こっているのか、そもそもどのようにしてこれが可能になったのでしょうか?
データベースからロードする ActiveRecord オブジェクトがあります。
valid?
このオブジェクトを呼び出すfalse
と、レールの一意の制約が満たされていないために返されます。少なくとも検証ではそうです。
データベースのスキーマを確認したところ、一意のフィールドにもインデックスが定義されているため、データベース レベルでも一意性が保証されています。
ここで何が起こっているのか、そもそもどのようにしてこれが可能になったのでしょうか?
@ object.errors.inspectで何が起こっているかを確認し、それに応じて修正する必要があります。
また、オブジェクトの有効性をいつチェックするか、つまり保存前または保存後も重要です。
よりエレガントな方法は、@object.save!
Rubyは、オブジェクトを保存しようとしたときに何がうまくいかなかったかを教えてくれるはずです。
データベース テーブルに一意のインデックスが定義されていない場合は、次のようになります。
もう少し詳しく言うと、データベースには列に一意のインデックスがあると思いましたが、それは「通常の」インデックスであることが判明しました。アプリケーションのある時点で、最初に検証せずにモデルが保存されたため、問題が発生しました。これにより、データベース内のエントリが一意ではなくなりました。トリガーを呼び出すことによりvalid?
、一意性をチェックする Rails 内部ルーチン (実装されている方法) が正しく false を返しました。
教訓: データベース レベルで一意のインデックスを必ず追加してください。