我想使用 laravel 模型中的删除函数从类别中删除一条记录,但这个函数让我成为一个奇怪的查询,没有意义。因此,我得到了一个错误(sql 约束失败)。 Laravel 执行以下奇怪的查询:从
t_category
删除,其中 t_category
.catLeft
> 505 和 t_category
.catRight
< 518 order by t_category
.catLeft
asc
为什么 laravel 不搜索 id 并删除找到的第一条记录?
我的控制器:删除功能
/**
* Remove the category
* @param Request $request
* @param String $no category's no
* @return \Illuminate\Http\RedirectResponse Redirect to the list of category
*/
public function remove(Request $request, $no){
// Get the category
$category = Category::findByNo($no);
if ($category == null)
return redirect('/gest/categories');
if ($category->isRoot())
return redirect('/gest/categories');
$parentID = Category::where('catParentId', $category->idCategory)->get();
try {
if(empty($parentID[0]["catNo"]))
{
$category->delete();
$request->session()->flash('message', ['result' => true,'title' => Lang::get('gest.deleteSucces.title'), 'msg' => Lang::get('gest.deleteSucces.msg', array('model' => $category->catNo.' - '.$category->catName))]);
}
else
{
$request->session()->flash('message', ['result' => false,'title' => Lang::get('gest.deleteCategoryParent.title'), 'msg' => Lang::get('gest.deleteCategoryParent.msg', array('category' => $category->catNo.' - '.$category->catName))]);
return redirect('/gest/categories');
}
}
catch (\Illuminate\Database\QueryException $e) {
if ($e->errorInfo[1] == "1451")// SQL code 1451 = Constraint fail
$request->session()->flash('message', ['result' => false,'title' => Lang::get('gest.deleteCategoryEchecContraintFail.title'), 'msg' => Lang::get('gest.deleteCategoryEchecContraintFail.msg', array('category' => $category->catNo.' - '.$category->catName))]);
else
$request->session()->flash('message', ['result' => false,'title' =>Lang::get('gest.deleteModelEchecUnknownError.title'), 'msg' => Lang::get('gest.deleteModelEchecUnknownError.msg', array('model' => $category->catNo.' - '.$category->catName))]);
}
return redirect()->back();
}
类别型号:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Exceptions\InvalidArgumentExceptionClass;
use App\Traits\Uuids;
use Baum\NestedSet\Node;
class Category extends Model {
use Node;
use Uuids;
/**
* The attributes that are mass assignable.
*
* [See laravel seeding documentation](https://laravel.com/docs/5.7/eloquent)
* @var array
*/
protected $fillable = ['catNo', 'catName'];
/**
* The attributes that aren't mass assignable.
* @var array
*/
protected $guarded = ['idCategory','catParentId','catLeft','catRight','catDepth'];
/**
* The attributes that should be hidden for arrays.
* @var array
*/
protected $hidden = ['idCategory','catParentId'];
/**
* The table associated with the model.
* @var String
*/
protected $table = 't_category';
/**
* The "type" of the primary key ID.
*
* @var string
*/
protected $keyType = 'string';
/**
* The primary key for the model.
* @var String
*/
protected $primaryKey = "idCategory";
/**
* Indicates if the IDs are auto-incrementing.
* @var boolean
*/
public $incrementing = false;
/**
* Indicates if the timestamps crated_at and updated_at are saved.
* @var boolean
*/
public $timestamps = false;
// 'parent_id' column name
protected $parentColumnName = 'catParentId';
// 'lft' column name
protected $leftColumnName = 'catLeft';
// 'rgt' column name
protected $rightColumnName = 'catRight';
// 'depth' column name
protected $depthColumnName = 'catDepth';
/**
* Get the kits that belong to the category
*
* @return array Kit
*/
public function kits() {
return $this->hasMany(Kit::class,'fkCategory')
->orderBy('kitNo','asc');
}
/**
* Get the Additional Items that belong to the category
*
* @return array AddItem
*/
public function addItems() {
return $this->hasMany(AddItem::class,'fkCategory')
->orderBy('adiName','asc');
}
/**
* Create an Category
*
* @param array $attributes
*
* @return \App\Models\Category
*
* @throws \App\Exceptions\InvalidArgumentExceptionClass
*/
public static function create(array $attributes = []) {
// Check if not duplicate No
if (static::where('catNo', $attributes['catNo'])->first()) {
throw InvalidArgumentExceptionClass::modelWithNoAlreadyExist(Category::class,$attributes['catNo']);
}
return static::query()->create($attributes);
}
/**
* Find a Category by its id
*
* @param string $idCategory
*
* @return \App\Models\Category|null
*/
public static function findById(string $idCategory) {
$category = static::where('idCategory', $idCategory)->first();
if (! $category) {
return null;
}
return $category;
}
/**
* Find a Category by its No
*
* @param string $catNo
*
* @return \App\Models\Category|null
*/
public static function findByNo(string $catNo) {
$category = static::where('catNo', $catNo)->first();
if (! $category) {
return null;
}
return $category;
}
}
我尝试使用销毁函数在函数中传递类别的 id,但出现同样的错误
查询的原因是您的模型正在使用
Baum\NestedSet\Node
特征。
鉴于删除单个节点可能需要删除或相关节点,嵌套集会构建适合您要删除的实例的查询。
要获得更简单的
DELETE FROM table WHERE id = x
查询,您需要删除 Node
特征,但这会破坏您想要保留的其他功能。
但是,我不认为你的问题是删除查询本身。你说:
所以,我得到了一个错误(sql 约束失败)作为结果
这可能是外键约束错误,这意味着您的其他模型之一依赖于您的类别模型。 如果您检查迁移,您可能会看到类似的内容
$table->foreign('category_id')->references('id')->on('categories');
或者
$table->foreignId('category_id')->constrained();
这意味着在删除类别之前,您需要删除附加到该类别的所有模型。 或者您可以定义
ON DELETE
行为,例如
$table->foreignId('category_id')
->constrained()
->onDelete('cascade');
这意味着当您删除 Category 实例时,所有相关实例也将被删除。
另一个选项是删除数据库中的外键约束,方法是编辑迁移并全新迁移数据库,或者创建迁移来更改受约束的表。
这里的文档应该有帮助