我一直在通过阶段 - 问题 - 答案开发一个调查类型的网络应用程序,现在我已经拥有保存每个问题的答案以及各自阶段中的问题的部分,但是在更新或删除阶段时,它是使用最新信息更新,但例如,如果您删除一个问题,它不会在视觉上显示,但在数据库中问题仍然存在,其答案占用空间
我在 img 中描述了问题所在
我在阶段有 2 个问题,如您所见,如果我删除一个,我将不得不保留如下图所示,但不是这样,它总是向我显示相同的问题,如果我明显添加它如果将其添加给我,我不知道如何删除数据库中的该关系以便更新
步骤Edit.blade.php
@extends('layouts.layout')
@section('content')
<form action="/dashboard/formulario/stages/{{ $stage->id }}" method="post">
@method('put')
<h2>ETAPA</h2>
<label>Titulo</label>
<input required type="text" name="title" value="{{ $stage->title }}">
<label>Descripcion</label>
<input required type="text" name="description" value="{{ $stage->description }}">
<h2>PREGUNTAS</h2>
<table>
<tbody>
@foreach($questions as $question)
<tr>
<td><input required name="questions[{{ $question->id }}]" type="text" value="{{ $question->title }}" ><td/>
<td>
<select name="types[{{ $question->id }}]" id="">
@foreach($types as $type)
@if($type->name == $question->type->name)
<option selected value="{{ $type->id }}">{{ @strtoupper($type->name) }}</option>
@else
<option value="{{ $type->id }}">{{ @strtoupper($type->name) }}</option>
@endif
@endforeach
</select>
</td>
<td>
<fieldset>
<legend>Respuestas</legend>
@foreach($question->answers as $answer)
@if($question->type->name == App\Type::OPCIONES['U'])
<input required name="answers[{{ $question->id }}][{{ $answer->id }}]" type="text" value="{{ $answer->title }}">
@elseif($question->type->name == App\Type::OPCIONES['C'])
<input required name="answers[{{ $question->id }}][{{ $answer->id }}]" type="text" value="{{ $answer->title }}">
@elseif($question->type->name == App\Type::OPCIONES['M'])
<input required name="answers[{{ $question->id }}][{{ $answer->id }}]" type="text" value="{{ $answer->title }}">
@endif
@endforeach
</fieldset>
<a href="">Agregar</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<input class="btn btn-primary" type="submit" value="Guardar">
</form>
@endsection
模型阶段
class Stage extends Model
{
protected $fillable = [
'id',
'title',
'description'
];
public function questions(){
return $this->hasMany('App\Question');
}
}
模型问题
class Question extends Model
{
protected $table = 'questions';
protected $fillable = [
'id',
'title',
'stage_id',
'type_id',
];
public function stage() {
return $this->belongsTo('App\Stage');
}
public function type(){
return $this->belongsTo('App\Type');
}
public function answers(){
return $this->hasMany('App\Answer');
}
}
模型响应
class Answer extends Model
{
public function __construct(array $attributes = ['title'])
{
parent::__construct($attributes);
}
protected $table = 'answers';
protected $fillable = [
'title',
'question_id'
];
public function question() {
return $this->belongsTo('App\Question');
}
public static function create(array $array) {
$answers = [];
return $answers;
}
}
更新的控制器的一部分
public function update(Request $request, Stage $stage)
{
$rules = [
'title' => 'max:150|string|unique:stages',
'description' => 'max:250|string'
];
$stage = Stage::findOrFail($stage)->first();
if ($request->get('title') != $stage->title ||
$request->get('description') != $stage->description) {
$this->validate($request, $rules);
$stage->title = $request->get('title');
$stage->description = $request->get('description');
$stage->save();
}
/*--------- SE RECORRE TODAS LAS PREGUNTAS ---------*/
foreach ($request->get('questions') as $id_q => $question) {
$question_test = new Question([
'id' => $id_q,
'title' => $question
]);
$type = Type::findOrFail($request->get('types')[$id_q]);
/*--------- SE ACTUALIZA LOS DATOS DE LA PREGUNTA ---------*/
$question_test->stage()->associate($stage);
$question_test->type()->associate($type);
if ($question_test->title == '') {
/*TODO: AGREGAR ENVIO DE ERROR*/
}
$question_test = Question::updateOrCreate([
'id' => $question_test->id
],[
'title' => $question_test->title,
'stage_id' => $question_test->stage_id,
'type_id' => $question_test->type_id
]);
/*--------- SE ACTUALIZA LOS RESPUESTAS DE LA PREGUNTA ---------*/
foreach ($request->get('answers') as $key => $answers) {
if ($id_q == $key) {
foreach ($answers as $id_a => $answer) {
if ($answer == '') {
/*TODO: AGREGAR ENVIO DE ERROR*/
}
$question_test->answers()->updateOrCreate([
'id' => $id_a
],[
'title' => $answer
]);
}
}
}
}
return redirect('/dashboard/formulario/stages');
}
迁移
阶段
class CreateStagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('stages', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('stages');
}
}
问题
class CreateQuestionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('questions', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->unsignedInteger('stage_id');
$table->unsignedInteger('type_id');
$table->timestamps();
$table->foreign('stage_id')->references('id')->on('stages');
$table->foreign('type_id')->references('id')->on('types');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('questions', function (Blueprint $table) {
$table->dropForeign('questions_type_id_foreign');
$table->dropForeign('questions_stage_id_foreign');
});
Schema::dropIfExists('questions');
}
}
答案
class CreateAnswersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('answers', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->unsignedInteger('question_id');
$table->timestamps();
$table->foreign('question_id')->references('id')->on('questions');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('answers', function (Blueprint $table) {
$table->dropForeign('answers_question_id_foreign');
});
Schema::dropIfExists('answers');
}
}
“问题”是 Laravel 没有一种(简单的)方法来同步一对多关系,就像它对多对多关系所做的那样,它就像一个魅力。
在这里你可以去几个解决方案:
为简单起见,我将公开我提出的最后一个解决方案,它相当初级,但它可以让您理解这个概念,以防您希望从模型中获得更专业的实现或添加您的服务/包。
我将只展示我需要的控制器方法的部分。