22
16

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.

Rails5の自己結合でハマる

22
Last updated at Posted at 2018-07-10

tl;dr

Rails5を利用している環境で、1対多の自己結合を実現させるために以下のようなコードを書いた。

class Hoge < ApplicationRecord
  has_many :children, class_name: 'Hoge', foreign_key: 'parent_id', dependent: :destroy
  belongs_to :parent, class_name: 'Hoge'
end

何度DBにレコードを登録しようとしても、毎回以下のようなエラーが発生して登録できない。

ActiveRecord::RecordInvalid: バリデーションに失敗しました: Parentを入力してください

いや、親に当たるレコードは、parent_id持たないんだよなぁ。。。ってことで盛大にハマったのでメモ。

原因

参考にしたサイトの情報が古い(Rails4以前のもの)ばかりだったので、Rails5からの仕様変更でハマっていた。

Rails5からはbelongs_toアソシエーションは、デフォルトでrequire: trueになったので、nullでの登録ができなくなっていた。
※確かに、belongs_toなのに、id設定しないとかレアパターンなので、デフォルトをそっちにするのは自然なんだけど。

逆に、これまで通り(Rails4みたいに)belongs_toのアソシエーションでnullを許容したい場合は、optional: true使えばエラーは発生しなくなる。

class Hoge < ApplicationRecord
  has_many :children, class_name: 'Hoge', foreign_key: 'parent_id', dependent: :destroy
  belongs_to :parent, class_name: 'Hoge', optional: true
end
22
16
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
22
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?