Laravelの「max」ルール (sizeの処理を追ってみた)

はじめに

tkfric.hatenablog.com

以前書いたような記事に似た内容

概要

公式のドキュメントでは

readouble.com

max:値

フィールドが最大値として指定された値以下であることをバリデートします。sizeルールと同様の判定方法で、文字列、数値、配列、ファイルが評価されます。


size:値

フィールドは指定された値と同じサイズであることをバリデートします。文字列の場合、値は文字長です。数値項目の場合、値は整数値です。配列の場合、値は配列の個数(count)です。ファイルの場合、値はキロバイトのサイズです。


こういう形で書かれているが、

'item_number' => 'max:10'

って書いても、数量10個のバリデーションではなく、文字長10文字のバリデーションになってしまったために本件に至る

Maxのバリデーション処理を読む

/**
 * Validate the size of an attribute is less than a maximum value.
 *
 * @param  string  $attribute
 * @param  mixed   $value
 * @param  array   $parameters
 * @return bool
 */
public function validateMax($attribute, $value, $parameters)
{
    $this->requireParameterCount(1, $parameters, 'max');

    if ($value instanceof UploadedFile && ! $value->isValid()) {
        return false;
    }

    return $this->getSize($attribute, $value) <= $parameters[0];
}

となっており、条件はあるが、size ルールを見ていることが分かった(ドキュメント通り)

Sizeのバリデーション処理を読む

/**
 * Get the size of an attribute.
 *
 * @param  string  $attribute
 * @param  mixed   $value
 * @return mixed
 */
protected function getSize($attribute, $value)
{
    $hasNumeric = $this->hasRule($attribute, $this->numericRules);

    // This method will determine if the attribute is a number, string, or file and
    // return the proper size accordingly. If it is a number, then number itself
    // is the size. If it is a file, we take kilobytes, and for a string the
    // entire length of the string will be considered the attribute size.
    if (is_numeric($value) && $hasNumeric) {
        return $value;
    } elseif (is_array($value)) {
        return count($value);
    } elseif ($value instanceof File) {
        return $value->getSize() / 1024;
    }

    return mb_strlen($value);
}

見ての通りで、数値でのmax判定をするためには条件があり、

maxとは別にLaravelが定義するnumericRuleを持っていることが必要な模様。

/**
 * The numeric related validation rules.
 *
 * @var array
 */
protected $numericRules = ['Numeric', 'Integer'];

とのことなので、numericinteger かを一緒に定義してあげれば良さそう

最後に

公式のドキュメントが少し不親切だなと思った