Rails: 親子まとめてのバリデーションは削除時に注意
Railsでは、親テーブルの1行に子テーブルの複数行が対応するhas_many
の関係を簡単に作れます。入力などの補助的な機能も各種整っていますが、バリデーションをかけようとした時に失敗したところがありました。
TL; DR
-
accept_nested_attributes_for
で削除しようとした子要素も、バリデーション時点ではまだ削除されていない
- そのため、モデルのCollectionにも入ったまま
-
marked_for_destruction?
でチェック可能
親子セットでのデータハンドリング
accept_nested_attributes_for
で削除しようとした子要素も、バリデーション時点ではまだ削除されていないmarked_for_destruction?
でチェック可能「1本の記事に複数のコメントが付く」ような、一対多の関係はWebアプリを作っていれば至るところに発生します。Railsでは、has_many
で結ばれた関係について、accept_nested_attributes_for
を行うことで、親についてのフォーム送信で子の作成・変更・削除などを一気に行ってしまうことができるようになります。さらに、nested_form
を使えば、そのような親子関係を受け入れるような入力フォームも、簡単に構築できます。
親子モデルへのバリデーション
モデルへのバリデーションは重要な機能ですが、親子セットのモデルでも親にかけたバリデーション、子にかけたバリデーションはそれぞれ動作します。そこで、子モデルの合計値を使うようなバリデーションをかけてみたところ、一見正常に動くように見えました。
消えてなーい!
ところが、その状態で子モデルを削除しようとしたところ、うまくバリデーションを通らないという事態が発生してしまいました。調べてみると、バリデーション段階では子モデルが消えていないということが判明しました。そして、destroyed?
もfalse
で、事態を解決できません。
正しいチェック方法
調べまわった結果、marked_for_destruction?
というのがこの状況をチェックする適切なメソッドだと判明しました。collections.reject(&:marked_for_destruction?)
で、削除されずに残るモデルたちだけのリストが得られます。
参考リンク
Author And Source
この問題について(Rails: 親子まとめてのバリデーションは削除時に注意), 我々は、より多くの情報をここで見つけました https://qiita.com/jkr_2255/items/288c44f26b4c13dd2d80著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .