image_pathとimage_orderのどちらかに値が入っていたらOK(どちらもnullはNG)なカスタムバリデーションルール 

# 目的
「通常アップロード時」と「セッションやストレージ一時フォルダ」でinputのname属性が異なる時に、
どちらか一方に値が入っていたらOKなバリデーションを作りたい。

例えば
・セッション前ならimage_pathが必須、しかしimage_orderはいらない
・セッション後ならimage_orderのみでもOK、しかしimage_orderを削除したらimage_pathが必須

# イメージ画像
![スクリーンショット 2025-03-09 10.09.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/25ca5e2d-c97f-42e2-8dfe-f48108850fa0.png)

# 手順
# ①required_without_allを追加
```CollectionRequest.php
public function rules()
{
    return [
        'title' => ['required', 'string', 'max:50'],
        'description' => ['nullable', 'string', 'max:10000'],
        'url_qiita' => ['nullable', 'url', 'max:500'],
        'url_webapp' => ['nullable', 'url', 'max:500'],
        'url_github' => ['nullable', 'url', 'max:500'],
        'is_public' => ['required', 'boolean'],
        'position' => ['required', 'integer'],
        // ✅どちらか一方に値が入っていればOK
        'image_path' => ['required_without_all:image_order'],
        'image_order' => ['required_without_all:image_path'],
    ];
}
```


# ②エラーメッセージを表示する準備
image_orderは、JavaScriptで作成するため記載なし
```○○.php
create.blade.php


<!-- 画像アップロード -->
<div class="p-2 w-full">
<div class="relative">
    // ✅ エラーメッセージ表示
    <x-input-error :messages="$errors->get('image_path')" class="mt-2" />
    <label for="image_path" class="leading-7 text-sm text-gray-600">画像</label>
    <!-- 見えない input -->
    <input multiple type="file" id="image_path" name="image_path[]" class="hidden" accept="image/*">
    {{-- <!-- セッションの画像データを送信 -->
    <input type="hidden" name="session_image_src" value="{{ json_encode(session('image_src', [])) }}">
    <input type="hidden" name="session_file_names" value="{{ json_encode(session('file_names', [])) }}"> --}}
    @foreach(session('tmp_images', []) as $tmpImage)
        <input type="hidden" name="tmp_images[]" value="{{ $tmpImage }}">
    @endforeach

    @foreach(session('file_names', []) as $fileName)
        <input type="hidden" name="session_file_names[]" value="{{ $fileName }}">
    @endforeach
    <br>
    <!-- カスタムアップロードボタン -->
    <label for="image_path" class="file-upload-btn inline-block px-4 py-1 text-sm text-gray-800 bg-gray-100 border border-gray-300 rounded-md shadow-sm cursor-pointer hover:bg-gray-200 active:bg-gray-300 transition">
      ファイルを選択
    </label>
    <!-- サムネイル一覧 -->
    <div class="relative mt-4">
        <label class="leading-7 text-sm text-gray-600">選択した画像：</label>
        <div id="imagePreviewContainer" class="grid grid-cols-3 gap-3 md:grid-cols-4 lg:grid-cols-5 md:gap-4 w-full place-items-center">
          <!-- 画像プレビューがここに追加される -->
        </div>
    </div>
    <!-- 大きなプレビュー画像 -->
    <div id="mainImageContainer" class="flex justify-center mt-4 hidden">
        <img id="mainImage" class="w-3/5 h-auto object-cover border rounded-lg" src="" alt="メイン画像">
    </div>
</div>
</div>
```


# ③エラーメッセージを任意で修正
```/Applications/MAMP/htdocs/Laravel/collections/lang/ja/validation.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | バリデーション言語行
    |--------------------------------------------------------------------------
    |
    | 以下の言語行はバリデタークラスにより使用されるデフォルトのエラー
    | メッセージです。サイズルールのようにいくつかのバリデーションを
    | 持っているものもあります。メッセージはご自由に調整してください。
    |
    */

    // ✅
    // 'required_without_all' => ':valuesのどれも指定しない場合は、:attributeを指定してください。',
    'required_without_all' => ':valuesは、必ず指定してください。',


    /*
    |--------------------------------------------------------------------------
    | Custom バリデーション言語行
    |--------------------------------------------------------------------------
    |
    | "属性.ルール"の規約でキーを指定することでカスタムバリデーション
    | メッセージを定義できます。指定した属性ルールに対する特定の
    | カスタム言語行を手早く指定できます。
    |
    */

    'custom' => [
        '属性名' => [
            'ルール名' => 'カスタムメッセージ',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | カスタムバリデーション属性名
    |--------------------------------------------------------------------------
    |
    | 以下の言語行は、例えば"email"の代わりに「メールアドレス」のように、
    | 読み手にフレンドリーな表現でプレースホルダーを置き換えるために指定する
    | 言語行です。これはメッセージをよりきれいに表示するために役に立ちます。
    |
    */

    'attributes' => [
      'password' => 'パスワード',
      'title' => 'タイトル',
      'description' => 'アプリ解説',
      'url_qiita' => 'Qiita URL',
      'url_webapp' => 'WebApp URL',
      'url_github' => 'GitHub URL',
      'is_public' => '公開種別',
      'position' => '表示優先度',
      // ✅
      'image_path' => '画像',
      'image_order' => '画像',
    ],

];
```