WeBlog

Webに関する情報を中心に発信してるブログ

【Rails】belongs_to オプションを設定した場合対象カラムに対する presence: true は自動で設定される

belongs_to オプションを設定した場合対象カラムに対する presence: true は自動で設定されるみたいなので、その検証をしてみる。

テーブルの関係

f:id:weblog_tec:20210424231028p:plain 今回はusersテーブルと、boardsテーブルを作成する

ユーザーが掲示板を作成するという感じになっている。

モデル

# user.rb
class User < ApplicationRecord
  has_many :boards, dependent: :destroy

  validates :last_name, presence: true
  validates :first_name, presence: true
end

まず、Userモデルではユーザーは複数の掲示板を作成できるので、has_many :boards

というアソシエーションを設定しています。

さらに、ユーザーが消えたら、ユーザーが作成した掲示板も消えるようにdependent: :destroyと書いています。

バリデーションとして、usersテーブルのlast_namefirst_nameカラムは空を許容しないように

presence: trueを指定しています。

# board.rb
class Board < ApplicationRecord
  belongs_to :user

  validates :title, presence: true
  validates :body, presence: true
end

Boardモデルでは、1つの掲示板は1人のユーザーによって作成されるので、belongs_to :userというアソシエーションを指定しています。

boardsテーブルのtitleカラムとbodyカラムは空を許容しないようにpresence: trueというバリデーションを指定しています。

ここで注目して欲しいには、boardsテーブルのuser_idカラムには空を許容しないというpresence: trueは書いていません。

当然、DB側でもNot Null制約をつけていません。

この状態で、boardsテーブルのuser_idカラムを空にしてINSERTした場合にどうなるか検証してみます。

検証してみる

rails consoleで検証してみます。

# Boardモデルのインスタンスを作成
> board = Board.new(title: 'タイトル', body: '本文')
=> #<Board id: nil, title: "タイトル", body: "本文", user_id: nil, created_at: nil, updated_at: nil, board_image: nil>

# バリデーションチェック
> board.valid?
=> false

# エラー内容を確認
> board.errors.full_messages
=> ["Userを入力してください"]

Boardモデルのインスタンスを作成して、user_idカラムには空にしています。

このインスタンスvalid?メソッドでバリデーションを実行すると、falseと返ってきました。

falseということは、バリデーションに引っかかっているということです。

titleカラムとbodyカラムは空を許容しないようにpresence: trueというバリデーションを指定していますが、user_idカラムには指定していません。

でもバリデーションに引っ掛かります。

rails5からアソシエーションを定義すると、usersテーブルと、boardsテーブルを紐づけるuser_idカラムにデフォルトでpresence: trueというバリデーション定義されるためです。

アソシエーションの定義であるbelongs_toのバリデーションであるpresence: trueに引っかかるとuser_idではなく、モデル名であるUserがエラーメッセージ内に表示されます。

なので、["Userを入力してください"]というエラーメッセージになっています。