以下のような中間テーブルを作成した。
class Tagging < ApplicationRecord
belongs_to :post
belongs_to :programming_language
end
create_table "taggings", force: :cascade do |t|
t.bigint "post_id"
t.bigint "programming_language_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["post_id"], name: "index_taggings_on_post_id"
t.index ["programming_language_id"], name: "index_taggings_on_programming_language_id"
end
add_foreign_key "taggings", "posts"
add_foreign_key "taggings", "programming_languages"
このテーブルに対するバリデーションテストを作成している時、現在何もバリデーションを実行するコードを書いていないのにバリデーションが発生したので原因を探った。
belongs_to
単体のデフォルト設定について
今回の場合のように単体で用いた場合外部キーカラムに値を設定していなければバリデーションが実行される。
optional: true
このoptionを渡すことによって外部キーカラムに値が入っていなかったり関連先に存在しないidを設定してもバリデーションが発生しない。
required: false
optional: true
と同様の機能を果たすオプションとしてrequired: false
が存在する。
これは、Rails5以前ではデフォルトでrequired: false
になっていたもので当時は外部キーに対するバリデーションを行うためにこのオプションをtrue
にしなければならなかった。
しかし、dhh曰くこの挙動はおかしいのでデフォルトでtrue
にしようとなったが、デフォルトでtrue
となるオプションはダメなんじゃないの?ということでoptional
という代替オプションが誕生したっぽい
これがその時の[issue]
(https://github.com/rails/rails/issues/18233#issuecomment-68256740)?