RailsのAPIを一から作っている時に遭遇しました。ググっても全然引っかからないし「もぅマヂ無理。。。リスカしょ。。。」ってなってました。ですが結構基本的なところでポカしてました。
結論から言えば,primary_key: trueを書き忘れていただけだったのですが。なぜこれでエラーが出たのか考えてみます。
Railsでprimary_keyのカラムを変える手順
Railsでprimary_keyを変更する手順は、以下の通りです。
-
create_tableメソッドに、id: falseを渡す -
create_tableメソッドのブロックに、primary_key: trueを渡したフィールドを作る
もしprimary_key自体いらねえよって時は,create_tableにid: falseを渡すだけでprimary_key自体作らなくなります。
お手本は、
class CreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
t.string :id, limit: 32, null: false, primary_key: true
t.string :password_digest, null: false
t.timestamps
end
end
end
こんな感じ。
validatesとは
validatesとは、rubyのスクリプト上でデータを検証して、おかしいデータを弾いてDBに書き込まれないようにする、みたいな機能です。
validatesの中でもuniqueness: trueに関しては、このバリデーションが走るたびにDBにフルアクセスが走ります。(MySQLならEXPLAINなどを実行してみるとわかります。) なので、扱いには十分に気をつける必要があります。
加えて余談ですが、RailsのいわゆるFormObjectとよばれる、ApplicationRecordを継承していないクラスにおいて、include ActiveModel::Modelをするクラス内では、uniqueness: trueを書くことができません。DBにクエリを発行しないvalidation、たとえば正規表現など、しか定義できないのですよね。
問題のMissingAttributeError
このエラーは、uniqueness: trueとid: falseとprimary_key指定忘れをフルコンボしていた時に出てきました。おそらくですが、save!する時にprimary_keyが内部的に空文字だったのだとおもいます。
もしエラーが出てきて、ググっても何も出てこない時は、大体簡単な設定ミスだったりすることが非常に多いなという体感があります………………