涉及关系时如何正确删除项目?



这是关于我正在尝试做的事情的一些背景,我正在制作一个带有调查的学校调查系统,这些调查具有可以添加到某个调查中的部分,这些部分具有属于它的问题,例如,一个部分可能是校园,该部分中的问题与学校校园有关。

我正在尝试删除一个部分,并删除属于该部分的所有问题,我的代码中途而废。这些问题有不同的"类别",即响应类型,例如是或否、排名、文本,最后是多项选择题。对于多项选择题,它们与问题选项有关系。

如果一个部分内部没有多项选择题,那么它会删除该部分和所有问题,但如果有,那么我会收到此错误

SQLSTATE[23000]:完整性约束冲突:1451 无法删除或更新父行:外键约束失败(unadeca_system.survey_question_options,约束survey_question_options_survey_question_id_foreign外键 (survey_question_id( 引用 'survey_questions (id(( (SQL:从survey_questions中删除,其中 survey_questions.survey_section_id = 1 且 survey_questions.survey_section_id 不为空(

关系是这样的

>节有许多>问题>有许多>问题选项

我在截面模型中像这样删除

public static function boot() {
parent::boot();
// when you are deleting a SurveySection, also delete all related questions
static::deleting(function($section){
$section->questions->each(function($question) {
$question->surveyQuestionOption()->delete();
$question->delete();
});
});
}

在控制器部分中

public function destroy($id)
{
DB::beginTransaction();
$section = SurveySection::findOrFail($id);     
$section->questions()->delete();
$section->delete();
DB::commit();
return back();
}

这就是我从模型中删除问题的方式

public static function boot() {
parent::boot();
// when you are deleting a SurveyQuestion, also delete all related options
static::deleting(function($question){
$question->surveyQuestionOption->each(function($option) {
$option->delete();
});
});
}

这就是我删除控制器中的问题的方式

public function destroy($id)
{
DB::beginTransaction();
$preg = SurveyQuestion::findOrFail($id);
$preg->surveyQuestionOption()->delete();
$preg->delete();
DB::commit();
return back();
}

如何修复此错误以删除所有问题,无论它是否是多项选择?

您是在关系对象而不是雄辩模型上调用delete

$question->surveyQuestionOption()->delete();

这最终将调用基本查询生成器的delete方法直接执行删除查询;它不会在模型上调用delete方法,这是触发模型事件的原因。

SectionController@destroy

$section = SurveySection::findOrFail($id);
$section->delete();

SurveySection@boot

static::deleting(function ($section) {
$section->surveyQuestions->each(function ($question) {
$question->delete();
});
});

SurveyQuestion@boot

static::deleting(function ($question) {
$question->surveyQuestionOptions->each(function ($option) {
$option->delete();
});
});

最新更新