Home > Software design >  Laravel update pivot table via chekbox items
Laravel update pivot table via chekbox items

Time:06-18

I have a problem when I try to update data on a pivot table using checkboxes. Here details:

So the tables are

documents

    public function up()
{
    Schema::create('documents', function (Blueprint $table) {
        $table->id();
        $table->string('NombreDocumento');
        $table->string('Descripcion');
        $table->string('CodDocumento');
        $table->timestamps();
    });
}

questionnaires

    public function up()
{
    Schema::create('questionnaires', function (Blueprint $table) {
        $table->id();
        $table->string('NombreCuestionario');
        $table->string('Descripcion');
        $table->string('CodQuestionario');
        $table->timestamps();
    });
}

And, my pivot table

document_questionnaire

    public function up()
{
    Schema::create('document_questionnaire', function (Blueprint $table) {
        $table->id();

        $table->unsignedBigInteger('document_id');
        $table->unsignedBigInteger('questionnaire_id');

        $table->foreign('document_id')->references('id')->on('documents')->onDelete('cascade');
        $table->foreign('questionnaire_id')->references('id')->on('questionnaires')->onDelete('cascade');

        $table->timestamps();
    });
}

Relation: many to many

MODELS: Document & Questionnaire

class Document extends Model
{
    use HasFactory;

    protected $fillable=["NombreDocumento","Descripcion","CodDocumento"];


    //relacion muchos a muchos
    public function questionnaires(){
        return $this->belongsToMany('App\Models\Questionnaire')->withTimestamps();
    }
}

class Questionnaire extends Model
{
    use HasFactory;

    protected $fillable=["NombreCuestionario","Descripcion","CodQuestionario"];


    //relacion muchos a muchos
    public function documents(){
        return $this->belongsToMany('App\Models\Document')->withTimestamps();
    }
}

This is what it looks like my form, so if I checked a document or even more, then when I click on "Actualizar" all informacion goes to the pivot table. enter image description here

View

<div >
<div >
    <div >
    <h1>Asignar Documentos a Questionario</h1>
  </div>
  <div  style="padding-left: 10px;padding-top: 2px; padding-bottom: 1px ;border: 3px double #B26A5B;">
    <p  style="margin-bottom: 0;"><strong>LÉEME</strong><br>Instrucciones</p>
  </div>
</div>
<div >
  <p >Nombre del Questionario:</p>
  <p >{{$questionnaire->CodQuestionario}}</p>
  <form method="post" action="/questionnaire/{{($questionnaire->id)}}">
  @method('PUT')
  @csrf
  <input type="hidden" name="_method" value="PUT">
  <h2>Listado de Documentos</h2>
  @foreach ($documents as $document)
    <div>
      <input type="checkbox" name="document[]" value="{{$document->id}}">
      <label >{{$document->CodDocumento}}</label> 
    </div>
  @endforeach
  <input type="submit" name="actualizarQuestionario" value="Actualizar" >
  </form>
</div>

And Controller: where I; use App\Models\Questionnaire; use App\Models\Document;

QuestionnaireController

public function index()
{
    //mostrar todos los datos
    $questionnaires=Questionnaire::all();
    return view ('/questionnaire/index',compact("questionnaires"));
}

public function store(Request $request)
{
    //validation rules
    $request->validate([
        "NombreCuestionario"=>'required',
        "Descripcion"=>'required',
        "CodQuestionario"=>'required'
    ]);

    //validation data
    $questionnaire=new Questionnaire;
    $questionnaire->NombreCuestionario=$request->NombreCuestionario;
    $questionnaire->Descripcion=$request->Descripcion;
    $questionnaire->CodQuestionario=$request->CodQuestionario;
    $questionnaire->save();

    Session::flash('cuestionario_creado','El cuestionario ha sido agregado correctamente');

    return redirect('/questionnaire/create');
}
public function edit($id)
{
    //
    $questionnaire=Questionnaire::findOrFail($id);
    $documents=Document::all();
    return view ('questionnaire.edit',compact("questionnaire","documents"));
}
public function update(Request $request, $id)
{
    //validation rules
    $request->validate([
        "document"=>'required',
    ]);

    $questionnaire=Questionnaire::findOrFail($id);
    $documents_id=Document::find([$id]);
    $questionnaire->Documents()->sync($request->documents_id);

    return'exito';
}
public function destroy($id)
{
    //
}

CodePudding user response:

The key on the form is document not document_id

//change

$questionnaire->Documents()->sync($request->documents_id);

//to

$questionnaire->Documents()->sync($request->document);

The update method should look like

public function update(Request $request, $id)
{
    //validation rules
    $request->validate([
        "document"=>'required',
    ]);

    $questionnaire=Questionnaire::findOrFail($id);
    $questionnaire->Documents()->sync($request->document);

    return 'exito';
}

The $id you are receiving in the update method is the id of Questionnaire and not Document

So Questionnaire::findOrFail($id) is okay, but $documents_id = Document::find([$id]); is not okay and is not required. The form contains $request->document as array of ids of Document selected via checkbox.

CodePudding user response:

You are searching for the document document using the questionnaire id. you should try something like this:

public function update(Request $request, $id)
{
    //validation rules
    $request->validate([
        "document"=>'required',
    ]);

    $questionnaire=Questionnaire::findOrFail($id);
    
    foreach($request->documents as $document_id) {
        
        $document = Document::find([$document_id]);
        $questionnaire->Documents()->attach($document);
    }

    return'exito';
}
  • Related