#php #laravel
#php #laravel
Вопрос:
У меня есть таблицы «проекты» и «задачи». Каждый проект может иметь несколько задач, поэтому его отношение «один ко многим».
Каскад OnDelete не работает для меня
Когда я удаляю проект, а затем отправляю задачи, я получаю сообщение об ошибке. Поэтому мне нужно, чтобы при удалении проекта он удалял все связанные с этим задачи. Это мои миграции;
Schema::create('tasks', function (Blueprint $table) {
$table->increments('task_id')->default($value=null)->unsigned();
$table->integer('proj_id')->nullable()->default($value=null)->foreign('proj_id')->references('proj_id')->on('projects')->onDelete('cascade');
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->increments('proj_id')->nullable()->default($value=null)->foreign('proj_id')->references('proj_id')->on('tasks')->onDelete('cascade');
И это мои модели;
class Project extends Model
{
protected $primaryKey = 'proj_id';
protected $fillable = ['proj_title','proj_desc','client_id','created_by'];
public function client (){
return $this->belongsTo('AppClient');
}
public function task (){
return $this->hasMany('AppTask');
}
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Task extends Model
{
protected $primaryKey = 'task_id';
protected $fillable = ['task_title','task_desc','status','priority','person_id','proj_title','proj_id','created_by'];
public function project(){
return $this->belongsTo('AppProject','proj_id');
}
Заранее спасибо
Комментарии:
1. Какую ошибку вы получаете? Или записи просто не удаляются?
2. Записи не удаляются
Ответ №1:
Если у вас нет веских оснований называть столбцы так, как у вас есть, я бы предложил следовать соглашению и изменить ваши миграции на…
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('project_id');
// other columns...
$table->foreign('project_id')
->references('id')->on('projects')
->onDelete('cascade');
});
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
// other columns...
});
У приращений не должно быть значения по умолчанию, поскольку оно является основным идентификатором и по умолчанию также не имеет знака.
Вам нужно будет обновить определения отношений в ваших моделях, если вы внесете вышеуказанные изменения. Это должно устранить вашу ошибку.
В качестве небольшого дополнения, довольно часто вам потребуется больше функциональности, чем просто каскадное удаление. Laravel предлагает события и прослушиватели, которые можно использовать для получения требуемого поведения — https://laravel.com/docs/5.8/eloquent#events . Это объясняет, как вы можете достичь того, что вам нужно, создав model observer.
Я бы рекомендовал потратить время на ознакомление с вышеизложенным. Хотя вы также можете получить те же результаты, добавив в свой Project
класс следующий метод,
protected static function boot() {
parent::boot();
static::deleting(function(Project $project) {
$project->tasks()->delete();
});
}
Комментарии:
1. Спасибо за ваш ответ, я рассмотрю это. Я добавил этот фрагмент кода, но получаю «SQLSTATE [42S22]: столбец не найден: 1054 неизвестных столбца ‘tasks.project_proj_id’ в ‘where clause’ »
2. Ах, либо обновите свой
Project
методtask()
доtasks()
(который лучше описывает отношения), либо измените код, который я опубликовал сtasks()
наtask()
.
Ответ №2:
Вам просто нужен внешний ключ в proj_id таблицы задач, а не наоборот, поэтому сначала удалите внешний ключ в основном столбце проектов.
Кроме того, тип столбца внешней таблицы задач должен соответствовать первичному ключу в таблице проектов. Вам нужно использовать UnsignedInteger, поскольку приращения в таблице проектов создадут первичный ключ целого числа с автоматическим приращением без знака.
$table->unsignedInteger('proj_id')->nullable()->default(null);
$table->foreign('proj_id')->references('proj_id')->on('projects')->onDelete('cascade');
Затем повторите миграцию, и она должна работать хорошо. Если у вас есть какие-либо ошибки, обновите свой ответ