【问题标题】:Laravel Soft Delete Unique column nameLaravel 软删除唯一列名
【发布时间】:2014-10-17 11:43:33
【问题描述】:

假设我有类别表,并且我在上面使用了软删除。现在我第一次添加了一个类别“测试”,之后我删除了这个类别,所以它会从数据库中更新我的 deleted_at 列。

现在,当我再次尝试添加名称为“Test”的类别时,它告诉我这个名称已被使用。我已经尝试过发布在Here 的规则。

但它不起作用。我在我的模型中使用了特征。下面是我的模型代码。

<?php
namespace App\Models;

use Illuminate\Support\Facades\Validator as Validator;
use Illuminate\Database\Eloquent\SoftDeletingTrait;

class Category extends \Eloquent {

    use SoftDeletingTrait;

    protected $dates = ['deleted_at'];

    /**
     * Guarded fields which are not mass fillable
     *
     * @var array
     */
    protected $guarded = array('id');

    /**
     * Name of the table used
     *
     * @var string
     */
    protected $table = 'travel_categories';

    /**
     * Validating input.
     *
     * @param array $input
     * @return mixed (boolean | array)
     */
    public static function validate($input, $id = null) {
        $rules = array(
            'name' => array('required','min:2','max:100','regex:/[a-zA-z ]/','unique:travel_categories,name,NULL,id,deleted_at,NULL'),
            'description' => 'Required|Min:2',
            'image' => 'image'
        );
        if ($id) {
            $rules['name'] = 'Required|Between:3,64|Unique:travel_categories,name,'.$id;
        }

        $validation = Validator::make($input,$rules);

        return ($validation->passes())?true : $validation->messages();
    }
}

【问题讨论】:

  • 根据我的理解laravel使用deleted_at列进行软删除,但数据库(mysql)不知道,它只知道它是datetime列,所以当你制作一个列唯一的数据库时,请遵循规则,保持独特...我认为这会对您有所帮助stackoverflow.com/questions/17458681/…

标签: php laravel unique soft-delete


【解决方案1】:

您了解软删除的目的吗?它只会将数据标记为非活动状态。不过它会在那里。

因此,如果您定义该列的值必须是唯一的,那么您不能创建其他类似的值是正确的。

  • 如果需要唯一,那么你应该restoreupdate数据。
  • 如果它可以有多个,那么你应该删除应用在它上面的唯一键(例如通过关系调用它)。

看:Laravel Eloquent Soft Deleting

【讨论】:

    【解决方案2】:

    首先:我不明白一些事情。您是否尝试验证创建和更新?那么为什么创建时允许 name 的长度为 2 到 100,而更新后的长度只有 3 到 64?

    第二:我建议放弃这个:

    protected $dates = ['deleted_at'];
    

    我看不出这样做的目的。

    第三,我要说到这里了,你想做什么?我想,你试图用这个过滤器'unique:travel_categories,name,NULL,id,deleted_at,NULL' 做的是检查活动类别中name 的唯一性。在这种情况下,应该可以。

    【讨论】:

    • 我在这里使用了验证规则。我想要的是当我创建或更新新记录时,它将对用户输入的值应用验证规则。 validate 方法中提到了规则。现在,当我尝试创建或更新新类别时,它应该检查 category name 的唯一性,它在数据库中有deleted_at = null
    【解决方案3】:

    我知道这个问题很老,但我有一个类似的问题,我偶然发现了这个。我想提一下我是如何为将来阅读它的任何人修复它的。我遇到的问题是,当存在具有相同值的旧记录但使用 soft_delete 删除时,Laravel 不允许我在唯一列中插入值。

    总而言之,目标是在插入新记录时忽略唯一列的旧软删除记录。我找到的解决方案是在表的迁移中。例如,假设我们有这些列:

    • 类别 - 唯一
    • deleted_at - 跟踪已删除的行

    在迁移中两者都应指定为唯一,如下所示:

     Schema::create('table_name', function (Blueprint $table) {
            $table->string("category");
            $table->softDeletes();
            $table->unique(["category", "deleted_at"]);
        });
    

    旁注:如果你像我一样已经有了表,你需要更改迁移并重新创建表(显然数据会丢失):

    • 删除表格
    • 更改迁移
    • 从迁移表中删除关于它的记录
    • 运行“php artisan migrate”再次创建表

    【讨论】:

    • 很抱歉,但这行不通。未删除的行在“deleted_at”列中将具有空值,空值不会触发“唯一”约束。该唯一约束仅保证您不会同时删除两个类别。
    • 或许有误会。我确实希望带有"deleted_at" = null 的行不会“触发唯一约束”。如果"deleted_at" = null,那么我们有一个活动行,这意味着它已被插入,但尚未被软删除。因此,它将被忽略,唯一检查将仅使用“类别”列中的值,这是我上面示例中的主要唯一列。这个设置对我的作用是,它允许唯一检查像往常一样工作,但忽略软删除的行。
    • 只是为了确认解决方案完美运行。
    • 太棒了!谢谢。
    • 不,sergio0983 是正确的,如果任何值为空,则不考虑整个唯一索引。如果您在此处看到 sqlfiddle,您会注意到使用此解决方案 sqlfiddle.com/#!9/1516b1/1 可以创建非唯一的表行
    猜你喜欢
    • 2017-06-02
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2016-07-06
    相关资源
    最近更新 更多