関連付け先のモデルのバリデーションを実行する「validates_associated」(Rails)

f:id:ryoutaku_jo:20190809015347p:plain

【結論】

validates_associatedは、関連付けられていている他のモデルのバリデーションを実行することができるヘルパー

・オブジェクトを保存しようとすると、関連付けられているオブジェクトごとにvalid?が呼び出される

・validates_associatedを、関連付けされているモデルの双方で使用すると、無限ループが発生してしまう為、注意が必要

【目次】

【本題】

validates_associatedについて

validates_associatedは、関連付けられていている他のモデルのバリデーションを実行することができるヘルパーです。

オブジェクトを保存しようとすると、関連付けられているオブジェクトごとにvalid?が呼び出される

「has_many」や「belongs_to」など、あらゆる種類の関連付けに対して利用できます。

class Book < ActiveRecord::Base
  has_many :pages
  belongs_to :library

  validates_associated :pages, :library
end

なお、validates_associatedを、関連付けされているモデルの双方で使用すると、無限ループが発生してしまう為、注意が必要です。

オプション

:message:カスタムエラーメッセージを設定できます。(デフォルトは「is invalid」)

:on:バリデーションを実行するコンテキストを指定できます。デフォルトでは、すべての検証コンテキストで実行されます。シンボルか、シンボルの配列を渡すことができます。(例: on: :create ,on: :custom_validation_context, on: [:create, :custom_validation_context])

:if:バリデーションを行うか指定できます。メソッドやProcなど、trueかfalseを返すものを渡して判定します。(例:if :: allow_validation, if: Proc.new { |user| user.signup_step > 2 }

:unless:バリデーションを行わないか指定できます。:ifと同様、メソッドやProcなど、trueかfalseを返すものを渡して判定します。(例:unless: :skip_validation, unless: Proc.new { |user| user.signup_step <= 2 }

参考情報

ActiveRecord::Validations::ClassMethods

ruby-on-rails – validates_associatedはアソシエーションの存在をチェックしない - コードログ

http://railsdoc.com/references/validates_associated

Active Record バリデーション - Rails ガイド

《今日の学習進捗(3年以内に10000時間に向けて)》

管理者がCSVからユーザー一括登録する機能の実装を行なっているが、管理者が知り得ない情報も必須項目に設定されている場合が想定されるので、必須項目を埋めなくても、登録が出来る仕様で実装を進めている。 しかし、子レコード(UserFormValue)のバリデーションがどうしても外せない。

validates_associatedはインポート時に処理を外すオプションが設定できたが、どうやらaccepts_nested_attributes_forの方でバリデーションがかかってしまっている様に見える。 メールアドレスと権限さえ正確に入力されていれば、ユーザーが初回登録した際に正しい内容に修正することで対応できるので、既存のバリデーションは通さず、メールアドレスと権限の内容を別途チェックする方法で一旦実装した。

今回の様な問題に対応する場合、Rails内部の動きを把握する必要があると感じた。 しかし、Railsのコードを読んでも、今ひとつ内容が理解できない部分が多い。 Rubyの文法などに関する深い知識が不足していることが原因の一つだと考えているので、更に掘り下げて学ぶ必要性を感じている。 RubyGOLDの取得を目指すのも良いかもしれないと考えている。

学習開始からの期間 :243日
今日までの合計時間:2324h
一日あたりの平均学習時間:9.6h
今日までに到達すべき目標時間:2219h
目標との解離:105h
「10,000時間」まで、

残り・・・「7676時間!」