Laravel 自作のカスタムルールに機能追加しがてら、value ヘルパー関数を使ってみる
まえがき
今回は、前回作成したカスタムルールに1つ機能(メソッド)を追加したいと思います。機能は、「とある条件を満たした時は、ルールを適用させない」というもので、value ヘルパー関数を使ってみます。
value ヘルパー関数って、ドキュメント見ても、使い方は分かっても、使い所はさっぱり分からなかったりします。
ややマニアックなヘルパー関数なので、この記事を読む価値(value)があるかどうかは、正直分かりかねます。🙇♂️
(Laravel 本体のソース見たりすると、結構出くわしたりしますが)
本題
という事で、前回のカスタムルールに上記機能を追加したいのですが、逆のアプローチの
「とある条件を満たせば、ルールを適用させる」も考えられる訳ですが、今回はそちらは割愛したいと思います。
メソッド名は、skipIf() とします。
以下のようなイメージです。
// 太郎さんの場合は、このチェックはスキップする
(new AllRequired('foo2', 'foo3'))->skipIf($name === '太郎')
ただ、場合によっては処理が複雑になる事も考え、無名関数を渡してその結果が true の時も、チェックをスキップするようにしたいので、以下の形もサポートする事にします。
(new AllRequired('foo2', 'foo3'))->skipIf(function () {
// 幾つかの処理して
return $name === '太郎';
})
という事で、引数にコールバック関数を渡された時は、それを実行した結果から判断しないといけなくなりました。何か面倒になってきました。そこで登場するのが、話題の value() ヘルパー関数です。
結果として、以下のようなコードを追加してやります。
class AllRequired implements ImplicitRule, DataAwareRule
{
public bool $skip = false;
public function passes($attribute, $value)
{
if ($this->skip) {
return true;
}
// 以下略
}
/**
* $callback の値又は実行結果が true 相当の時は、validation をスキップとする
*
* @param mixed $callback
* @return object $this
*/
public function skipIf($callback)
{
$this->skip = !! value($callback);
return $this;
}
value() ヘルパー関数は、コールバック関数の時はその実行結果を、コールバック関数以外の時はその値を返してくれます。お陰で、何か楽できた気分です。
おわりに
さて、この value() ヘルパー関数、こんな感じになっています。(GitHub:ソース)
if (! function_exists('value')) {
/**
* Return the default value of the given value.
*
* @param mixed $value
* @return mixed
*/
function value($value, ...$args)
{
return $value instanceof Closure ? $value(...$args) : $value;
}
}
なんだ、1行か。という印象もありますが、それ以上に何故「Collections」の中に?という印象が強い関数でした。
ミス等ありましたらコメント下さい。
Discussion