web-dev-qa-db-ja.com

Laravel:フォームリクエストの検証で無視ルールを使用する方法

Laravelには、「except」句を含む「unique」ルールがあります。検証ドキュメントから、次の形式になります。

unique:table,column,except,idColumn

私のアプリケーションには「ショップ」エンティティがあります。ユーザーがショップのプロファイルを更新すると、検証ルールが次のように構成されたフォームリクエストが表示されます。

public function rules()
{
    return [
        'shop.name' => 'required|string|max:100|unique:shops,name,except,id',
    ];
}

(私のshopsテーブルの主キーはidです)。

問題は、Laravelが 'except'句に気付かないことです。これは、ショップIDがフォームリクエストに挿入されていないため、(一種の)意味があります。idを挿入できます。別のフォーム値としてですが、それは機能していないようです。

このルールをフォームリクエストで機能させるにはどうすればよいですか?

4
Kim Prince

except句をuniqueルールに使用するには、ルールで無視するレコードのフィールドのvalueを指定する必要がありますルール自体に直接

したがって、すべてのレコードに一意のnameフィールドが必要な場合exceptリクエストが更新されるレコードで、無視するIDフィールドの値を追加する必要があります。

_class UpdateShopRequest extends FormRequest
{
    ...
    public function rules() 
    {
        return [
            'shop.name' => 'unique:shops,name,' . $this->shop['id'],
        ];
    }
}
_

示されているように、このルールにより、いずれかの行に同じショップ名が含まれている場合、検証が失敗しますただし行のidが_$this->shop['id']_と一致する場合。この例では、質問が配列入力の検証を実行しているため、フォームにレコードのID属性の配列入力フィールドが含まれていることを前提としています。

_<input type="hidden" name="shop[id]" value="{{ $shop->id }}">
_

...これにより、他のリクエストと同じように、リクエスト内の値をフェッチできます。より一般的には、レコードIDをルートパラメータとして渡します。これは、リクエストのroute()メソッドを使用して取得できます。

_$shopId = $this->route('id');
_

...これは、次のように定義されたルートがある場合に機能します。

_Route::post('shops/{id}', ...);
_

unique検証ルールの4番目のパラメーターを使用すると、except句を適用する列を指定でき、デフォルトはidであるため、そのままにしておくことができます。レコードのIDを比較します。

特に他の多くのルールがあるフィールドの場合、列の値を連結するだけでは、ルールは少し不器用に見えます。バージョン5.3以降、Laravelは、unique句を含むexceptルールを作成するためのより洗練された構文を提供します。

_use Illuminate\Validation\Rule;
...
return [
    'shop.name' => [ 
        'required', 
        'string', 
        'max:100', 
        Rule::unique('shops', 'name')->ignore($shopId, 'optional_column'), 
    ],
];
_
12
Cy Rossignol

この例では、質問が配列入力の検証を実行しているため、フォームにレコードのID属性の配列入力フィールドが含まれていることを前提としています。<input type="hidden" name="shop[id]" value="{{ $shop->id }}">

Laravel 5.8:私は今あなたに解決策を試しました入力を追加せずに、それはうまく機能しています。 Laravel Shopオブジェクトをリクエストに渡すため(dd()でrules()に表示)

ただ:

`public function rules()
{
    return [
        'name' => 'unique:shops,name,'.$this->shop->id
    ];
}`