web-dev-qa-db-ja.com

laravel validationを使用して、削除されていないアイテム間で名前が一意かどうかを確認します

特定のプロジェクトでアイテムの名前が既に使用されているかどうかを確認するコントローラーにポストする単純なフォームがあります。そうであれば、エラーを返します。これは私がそのために使用しているコードです:

'name'    => 'required|min:1|unique:versions,name,NULL,id,project_id,'.$project->id,

私が遭遇した問題は、ハード削除の代わりに、ソフト削除を使用してそれらをデータベースから削除していることです。つまり、たとえば、「Test」は名前の後に一度だけ名前として使用できます削除されました。

ソフト削除されていないアイテムの中で、そのプロジェクトに固有のものであることを確認するにはどうすればよいですか?

18
Samsquanch

あなたはこれを試すことができます:

'name' => 'required|min:1|unique:versions,name,NULL,id,deleted_at,NULL'

これにより、nameテーブルのversionsが一意になることが確認されます。レコードがソフト削除され、同じ名前の名前が付けられている場合、カウントされません。つまり、名前が受け入れられます同じ名前のソフト削除されたレコードが存在する場合でも。

更新時にモデルを無視するには、最初のidの代わりにnameの後にNULLを渡す必要があります。

pdate:また、次のようなものを使用して独自のカスタムルールを追加することもできます。

// You can declare it inside your controller method before you run validation
Validator::extend('unique_project', function($attribute, $value, $parameters)
{
   // $attribute will contain field name, i.e. name
   // $value will contain the value in the $attribute/name
   // $parameters will be an array of arguments passed
   // i.e. [0] => arg1, [1] => arg2, [2] => arg3 and so on

   return true for valid and false for invalid

});

次のように使用できます。

'name' => 'required|min:1|unique_project:arg1,arg2,arg3' // add more args if needed
34
The Alpha

私はこの質問が古いことを知っていますが、同様の問題の解決策を探しているときにこれに偶然遭遇しました。カスタム検証コードは必要ありません。

「name」と「short_name」が各ユーザー(user_id)に対して一意である必要がある元帳コードのデータベースがあります。ソフト削除を有効にしているので、特定のユーザーの削除されていない行の間でのみ一意にする必要があります。

これは検証文字列を返す私の関数です:

_protected function validation_data($user_id, $update_id = "NULL") {
        return [
        'name' => "required|max:255|unique:ledger_codes,name,$update_id,id,deleted_at,NULL,user_id,$user_id",
        'short_name' => "max:255|min:3|unique:ledger_codes,short_name,$update_id,id,deleted_at,NULL,user_id,$user_id",
        'description' => 'max:255',
        ];
    }
_

一意のバリデーターの引数文字列構文について疑問に思う方は、次のとおりです。

  • arg 0:データベース内のテーブル名
  • arg 1:値が一意であるフィールド名
  • arg 2:無視される単一のID(使用しない場合は大文字のNULLに設定します。)
  • 引数3:単一のIDが存在するフィールド。デフォルトは 'id'なので、それを使用せず、さらに引数がある場合は、文字列 'id'を使用します。
  • arg 4/5:where句のフィールド名と値のペア(この例ではwhere('deleted_at',null))。
  • 引数6/7:別のフィールド名と値のペア(この例ではwhere('user_id', $user_id))。
  • 引数8/9:別のフィールド名と値のペア
  • 引数10/11:別の......
    ... 等々。

フィールド名と値のペアの値フィールドは、一致する値、NULL、またはNOT_NULLのいずれかです。

21
mp035

誰かがRuleクラスを使用して解決策を探している場合。

use Illuminate\Validation\Rule;

class UpdateArticleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $data = $this->request->all();

        return [
            'slug' => [
                'required',                
                Rule::unique('articles')->ignore($data['id'])->whereNull('deleted_at')
            ]
        ];
    }
}

基本的には、deleted_atフィールドはnullではありません。

ignore関数と一緒に使用できるメソッドは次のとおりです: https://laravel.com/api/5.7/Illuminate/Validation/Rules/DatabaseRule.html

7
Scofield

レコードを追加する場合

'name' => [
                'required',
                'string',
                'min:3',
                Rule::unique('products')->where(function ($query) {
                    return $query->where('store_id', Auth::user()->store_id);
                })->whereNull('deleted_at'),                
            ],

そのレコードを編集するには

'name' => [
                'required',
                'string',
                'min:3',
                Rule::unique('products')->where(function ($query) {
                    return $query->where('store_id', Auth::user()->store_id);
                })->ignore($request->id, 'id')->whereNull('deleted_at'),                
            ],
1
Aamir Anwar

メソッド作成時:

public function store(Request $request)
{

    $request->validate([

        'name'=>'required|unique:form_types,name,NULL,id,deleted_at,NULL',

    ]);

    // Write your code here

}

更新方法:

public function update(Request $request, $id)
{

    $request->validate([

        'name'=>'required|unique:form_types,name,'.$id.',id,deleted_at,NULL',

    ]);

    // Write Code here

}
1