我有一个Laravel 8.x应用程序,它有一个包含列的数据库表:blockID (primary key), blockName, createdBy, and delete (boolean)
。
当用户添加一个新块并提交表单时,我想验证blockName
是唯一的。如果它是唯一的,则blockName
将存储在数据库中,删除列设置为false。当用户单击删除按钮时,相应行的删除列将更新为true。尽管数据仍保留在数据库中(未被永久删除(,但不应在网页上显示。
这是我目前使用的验证代码:
$validatedValues = $request->validate([
'blockName' => 'required|unique:blocks',
]);
对于删除,这是我实现的代码:
public function destroy($id)
{
$block = Block::find($id);
$block->delete = true;
if ($block->update()) {
return response()->json(['success' => true]);
}
}
我的问题是:我如何确保当Laravel验证blockName为唯一时,它会排除删除列设置为true的记录?如果有任何见解或建议,我将不胜感激。
感谢您的帮助!
谨致问候。
如果尚未在基础数据库表的blockName
列上设置唯一条件。然后你可以做下面这样的事情来解决你的问题。
$request->validate([
'blockName' => 'required|unique:blocks,delete,FALSE'
]);
注意:我不太确定这是否是将布尔值传递给验证器的方式。如果使用软删除,下面的代码将完美工作
我建议你实现laravel模型的SoftDeletes
特性,让你的生活更简单。这将在表中添加一个deleted_at
列。Laravel将自动为您省略其中已删除_at的行。调用模型的普通delete方法只会设置deleted_at字段,不会将其从DB中删除。这将减轻您更新delete
列的负担。
如果您选择这样做。验证如下所示。
$request->validate([
'blockName' => 'required|unique:blocks,deleted_at,NULL'
])
您可以创建一个自定义验证规则来包含您的逻辑。
php artisan make:rule UniqueOrDeleted
App\Rules\UniqueOrDeleted.php
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
class UniqueOrDeleted implements Rule
{
/**
* The model we're going to be performing the query against
*
* @var string
*/
private $model;
/**
* Create a new rule instance.
*
* @param string $model
*
* @return void
*/
public function __construct(string $model)
{
$this->model = $model;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return $this->model::query()
->where($attribute, $value)
->where('delete', true)
->count();
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The validation error message.';
}
}
然后您可以按如下方式使用它。
$validatedValues = $request->validate([
'blockName' => ['required', new UniqueOrDeleted(Block::class)],
]);
我们提供了一个model
作为构造函数参数,以防您想在其他地方使用相同的概念,这意味着您不必硬编码表名或任何东西。您可以进一步理解这个概念,并提供第二个参数,该参数将指定表中delete
字段的名称。
您需要这样做:
Rule::unique('blocks', 'blockName')->where(fn ($qry) => $qry->where('delete', 0));