【问题标题】:laravel 4.1 unique validation on update failslaravel 4.1 更新时唯一验证失败
【发布时间】:2014-11-30 06:22:10
【问题描述】:

Laravel 4.1。我想更新一个城市,检查规则,但它在唯一检查时失败了。

规则:

public static $rules = [
    'name' => 'required|alpha_dash|unique:cities',
    'slug' => 'alpha_dash|unique:cities',
    'seo_title' => 'required|max:60|unique:cities',
    'seo_description' => 'required|max:160|unique:cities',
    'rank' => 'integer',
    'visible' => 'integer'
];

我知道,我可以:

'name' => 'required|alpha_dash|unique:cities, name, ##',

where ## - id,但我不能动态地将 id 设置为更新的。

'name' => "required|alpha_dash|unique:cities, name, $id", // doesnt work
'name' => "required|alpha_dash|unique:cities, name, $this->id", // doesnt work

有什么办法可以正常做吗?

【问题讨论】:

  • 用这个生成的查询是“WHERE ”... @mozg

标签: php validation laravel laravel-4


【解决方案1】:

您可以通过不同的方式进行操作。

一种简单的方法是根据不同的操作使用不同的规则。创建模型时,您将使用当前拥有的规则。

当您更新模型时,您会将unique:cities 更改为exists:cities

我通常通过验证服务来做到这一点。

您在 services/ 中创建一个基本的抽象验证器,它有一个 pass() 函数。

对于每个模型,您创建一个 ModelValidator ,在您的情况下为 CityValidator。你把你的规则放在哪里:

public static $rules = [
    'new'=>[
    'name' => 'required|alpha_dash|unique:cities',
    'slug' => 'alpha_dash|unique:cities',
    'seo_title' => 'required|max:60|unique:cities',
    'seo_description' => 'required|max:160|unique:cities',
    'rank' => 'integer',
    'visible' => 'integer'],

    'edit'=>[
    'name' => 'required|alpha_dash|exists:cities',
    'slug' => 'alpha_dash|unique:cities',
    'seo_title' => 'required|max:60|exists:cities',
    'seo_description' => 'required|max:160|exists:cities',
    'rank' => 'integer',
    'visible' => 'integer'
    ]
];

【讨论】:

  • 是的,我知道那样,但也许有办法在那里传递 id ?在我的例子中,4 个重复的规则并不是很酷
  • 你的方式太复杂了,唯一规则中有一个ID用于此目的,但没有很好的方式传递ID
  • 是的,看到这个解决方案,不喜欢它,觉得更漂亮。很遗憾,没有内置的解决方案可以传递该 ID。不知道为什么没有改进。还是谢谢
  • btw 存在不检查字段中的值是否重复
【解决方案2】:

第三个参数接受一个被忽略的值...如果你想做一个WHERE 子句,这样做:

'name' => array("required", "alpha_dash", "unique:cities,name,null,id,id,$this->id"...

文档说:

添加额外的 Where 子句

您还可以指定更多条件,这些条件将添加为“where” 查询的子句:

'email' => 'unique:users,email_address,NULL,id,account_id,1'

在上述规则中,只有 account_id 为 1 的行才会包含在唯一检查中。

通过例子学习:

email => unique:users,email_address,id,NULL,field_1,value_1,field_2,value_2,field_x,value_x

生成查询:

SELECT
    count(*) AS AGGREGATE
FROM
    `entries`
WHERE
    `email_address` = ?
AND `id` <> NULL
AND `field_1` = `value_1`
AND `field_2` = `value_2`
AND `field_x` = `value_x`

【讨论】:

  • 第三个参数不是一个值 - 它是要被忽略的 ID。 不需要传递 where。要更新 14 行,我只需将 14 作为第三个参数传递:唯一:城市,名称,14。但我不能动态传递 id。 $this->id 不起作用
【解决方案3】:

我找到了一种优雅的方式来使用fadion/ValidatorAssistant

<?php

use Fadion\ValidatorAssistant\ValidatorAssistant;

class CityValidator extends ValidatorAssistant {

    // standard rules
    public static $rules = [
        'name' => 'required|alpha_dash',
        'slug' => 'alpha_dash',
        'seo_title' => 'required|max:60',
        'seo_description' => 'required|max:160',
    ];

    // some preparation before validation
    protected function before()
    {
        // Inject the given city id into the unique rules
        $this->rules['name'] .= 'unique:cities,name,' . $this->inputs['id'];
        $this->rules['slug'] .= 'unique:cities,slug,' . $this->inputs['id'];
        $this->rules['seo_title'] .= 'unique:cities,seo_title,' . $this->inputs['id'];
        $this->rules['seo_description'] .= 'unique:cities,seo_description,' . $this->inputs['id'];
    }

当您需要多个字段在数据库范围内唯一时,几乎可以肯定有一种更优雅的方法可以做到这一点,但是当您只需要一个部分是唯一的时候,上述方法非常有效。

【讨论】:

  • 我正在使用一个函数,我将它传递给验证器,例如Model::rules($id);。该函数检查唯一规则并连接指定的 id。简单而有效。
猜你喜欢
  • 2019-02-26
  • 1970-01-01
  • 2020-03-30
  • 2014-06-28
  • 2014-08-20
  • 2018-07-17
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多