Laravel 5.6根据用户群验证唯一规则(高级)

时间:2018-08-23 20:15:19

标签: php laravel validation

我有以下表格模式。

     Schema::create('wallets', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        $table->string('title');
        $table->string('code');
        $table->text('description')->nullable();
        $table->decimal('opening_balance', 10, 2)->default(0);
        $table->tinyInteger('active')->default(true);
        $table->integer('sort')->default(0);
        $table->timestamps();
        $table->softDeletes();

        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });

我正在为我的项目使用表单请求,如下所示。 我有如下所示的WalletStoreRequest.php和WalletUpdateRequest.php。

WalletStoreRequest.php

public function rules()
{
    return [
        'title'           => 'required|unique:wallets,
        'code'            => 'required',
        'opening_balance' => 'required',
        'active'          => 'required|numeric',
        'sort'            => 'required|numeric',
    ];
}

WalletUpdateRequest.php

public function rules()
{
    $id = \Request::segment(4);
    return [
        'title'           => 'required|unique:wallets,id,' . $id,
        'code'            => 'required',
        'opening_balance' => 'required',
        'active'          => 'required|numeric',
        'sort'            => 'required|numeric',
    ];
}

我希望在每个用户的基础上进行验证,就像每个用户在标题栏中都可以有一个名为“ cash”的同名钱包示例一样,但是如果用户再次创建一个名为“ cash”的新钱包,则验证应该说您拥有已经。

更多说明:

用户A:

  1. 现金
  2. 银行ABC
  3. 借记卡

用户B:

  1. 现金(与用户A的标题相同)已允许
  2. XYZ银行
  3. 信用卡
  4. 现金(不应再次允许)不允许使用

标题字段的规则是什么?请指导情况存储和更新的最佳做法。

2 个答案:

答案 0 :(得分:1)

假设总会有一个登录用户,您可以执行以下操作:

WalletStoreRequest.php

'title' => 'required|unique:wallets,title,NULL,id,user_id,'. $this->user()->id,

WalletUpdateRequest.php

'title' => 'required|unique:wallets,title' . $id . ',id,user_id,' . $this->user()->id,

唯一字符串分为几部分:

  • wallet,title:这是表和列的名称。
  • $id .',id':这是可以忽略的值和列名(本质上是where not
  • user_id,' . $this->user()->id:这是行中必须匹配的列名和值(本质上是where子句)。您可以根据需要继续链接其中的许多链接。

如果您使用Laravel> = 5.3,则可以使用Rule类:

'title' => [
    'required',
    Rule::unique('wallets', 'title')->ignore($id)->where(function ($query) {
        $query->where('user_id', $this->user()->id);
    })
]

您需要将use类的Rule语句添加到您的Request类:

use Illuminate\Validation\Rule;

有关documentation的更多信息,请查看


您可以轻松地将2个请求类合并为一个,例如:

return [
    'title'           => [
        'required',
        Rule::unique('wallets', 'title')->ignore(optional($this->route('wallet'))->id)->where(function ($query) {
            $query->where('user_id', $this->user()->id);
        }),
    ],
    'code'            => 'required',
    'opening_balance' => 'required',
    'active'          => 'required|numeric',
    'sort'            => 'required|numeric',
];

上面使用的是optional帮助方法。上面还假设您正在使用隐式模型绑定,并且该变量称为wallet

答案 1 :(得分:-1)

这应该为您解决问题:

'title' => Rule::unique('wallets')->where(function ($query) use ($id) {
    return $query->where('user_id', $id);
})

在复杂的规则上使用Rule引用总是很好。

https://laravel.com/docs/5.6/validation#rule-unique

一个小注意事项:

如果您的网址看起来像这样:/some/path/to/{id}

您可能想考虑进行$this->route('id')来从url中检索参数。