10
7

More than 3 years have passed since last update.

【Rails】validatesとvalidates_associated違い

Last updated at Posted at 2020-11-30

はじめに

モデルのバリデーションでうまくいかなかったり、勘違いしていた記述を整理し、学びがあったので書きます。

状況

親モデルとしてproductモデル、子モデルとしてproduct_imageモデルがあります。
productを作成した時は必ず一つ以上のproduct_imageのレコードがあることが条件

以下のようなモデルの記述です。

class Product < ApplicationRecord
  has_many :product_images, dependent: :destroy
  accepts_nested_attributes_for :product_images, allow_destroy: true

  validates_associated :product_images
  validates :product_images, presence: true
end

class ProductImage < ApplicationRecord
  mount_uploader :image, ImageUploader
  belongs_to :product

  validates :image, presence: true
end

ここでタイトルの内容のように違いを説明します。

validates_associatedについて

validates_associated :product_images

これでproduct_imageが無い時はバリデーションがかかるものだと思っていたがそれは誤りです。
この表記は「関連付けされている両方のモデルでバリデーションを実行する」というもの。
私なりの言葉ではアソシエーションされてる先?別?モデルのカラムに対するバリデーションもかけますよ!というもの。

そもそもproduct_imageが空の場合とは意味が違います。

ではどうすればいいのか。
普通にバリデーションかけたいが、productモデルにはproduct_imageのカラム無いし・・・
と悩んでいました。

答えはすでに記述してあるとおり以下の記述です。


validates :product_images, presence: true

validatesについて

ここでもまだ私には疑問がありました。
validatesの後に記述するのはカラム名では?と。

間違いではないですが、不足している点があります。
その考え方で学びがありました。

わかりやす言えば以下のようにproduct.のあとに付けれるものはvalidates :という表記で条件(presence: trueなど)が付けれるということです。


product.name           #プロダクトの名前(カラム名)
product.price      #プロダクトの金額(カラム名)
product.product_image #プロダクトの画像(アソシエートされてるモデル名)

たしかにアソシエーションかけてるとproduct.で値が取り出せます!
これの考え方でかなりすっきりしました!

10
7
1

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
10
7