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が内部的に空文字だったのだとおもいます。
もしエラーが出てきて、ググっても何も出てこない時は、大体簡単な設定ミスだったりすることが非常に多いなという体感があります………………