4

The database contains 3 tables 1 table called species, panel and a crosstable species_panel. The relationship is the following 1 panel can contain many species. Therefore, I use a 1 to many relationships. The data that should be inserted panel table name en description. The species table stays unchanged. And also data should be inputted into the cross table.

For my panel table: A key is added but the columns name and description just got the NULL imported instead of the value. For my crosstable: Nothing got inserted.

Why can't my data be inserted? I am missing something, I don't see it. Thanks for the help.

The species table

        +----+-----------------+
        | id | name            |
        +----+-----------------+
        | 1  | Spider Monkey   |
        +----+-----------------+
        | 2  | Squirrel Monkey |
        +----+-----------------+
        | 3  | Vervet Monkey   |
        +----+-----------------+
        | 4  | Dorset Horn     |
        +----+-----------------+
        | 5  | Dorper          |
        +----+-----------------+
        | 6  | Javan Warty Pig |
        +----+-----------------+
        | 7  | Wild Boar       |
        +----+-----------------+

How data in the other tables should look.

Panel table

        +----+------+-------------+
        | id | name | description |
        +----+------+-------------+
        | 1  | P001 | Monkeys     |
        +----+------+-------------+
        | 2  | P002 | Sheeps      |
        +----+------+-------------+
        | 3  | P003 | Porks       |
        +----+------+-------------+

species_panel table

        +----+----------+---------+
        | id | panel_id | species |
        +----+----------+---------+
        | 1  | 1        | 1       |
        +----+----------+---------+
        | 2  | 1        | 2       |
        +----+----------+---------+
        | 3  | 1        | 3       |
        +----+----------+---------+
        | 4  | 2        | 4       |
        +----+----------+---------+
        | 5  | 2        | 5       |
        +----+----------+---------+
        | 6  | 3        | 6       |
        +----+----------+---------+
        | 7  | 3        | 7       |
        +----+----------+---------+

My code:

species.vue

            <template>
         <b-card title="Database" >
            <div class="container-fluid">
                    <div class="row md-4" v-show="selectedSpecies.length > 0">
                        <div class="col-2">
                            <label for="example-date-input">Delivery date</label>
                        </div>
                        <div class="col-6">
                            <label for="example-date-input">Describe your panel</label>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-2">
                            <b-form-input v-model="date" class="form-control" type="date" value="getDate" ></b-form-input>
                            <pre class="mt-3 mb-0">{{ date }}</pre>
                        </div>
                        <div class="col-6">
                            <b-form-input v-model="description" placeholder="Enter some text"></b-form-input>
                            <pre class="mt-3 mb-0">{{ description }}</pre>
                        </div>
                        <div class="col-4">
                            <button class="btn btn-primary custom-button-width" center-block>Request pool</button>
                        </div>
                    </div>
                <div class="row">
                    <div class="col-sm-8">
                        <b-table class="col-sm-12 table-sm" show-empty tbody-tr-class="addPointer"
                            :items="filterSpecie"
                            :fields="fields"
                            @row-clicked="clickedspecie"
                        >
                        <template slot="name" slot-scope="row">
                            {{row.item.name}}
                        </template>
                    </b-table>
                    </div>  
                    <div class="col-sm-4">
                        <b-table class="col-sm-12 table-sm" tbody-tr-class="addPointer"
                            :items="selectedSpecies"
                            :fields="selectedfields"
                            @row-clicked="clickedselectedSpecie"
                        >
                        <template slot="name" slot-scope="row" >
                            {{row.item.name}}
                        </template>
                        </b-table>
                    </div>      
                </div>
            </div>
         </b-card>
        </template>

Part of javascript

           // used to get ids from my array
            idsSelecter (array){

            this.selectedSpecies.forEach(obj => {
                array.push(obj.id);
                });
            console.log(array);
            return array;
    },
                 storePanel: async function(){
            axios.post('/panel',{

                description: this.description,
                date: this.date,
                selectedIds: this.idsSelecter(selectedIds)
            })
            .then(function (response) {
                console.log(response);
            })
            .catch(function (error) {
                console.log(error);
            })
            .finally(function () {
                // always executed
            });

species.php

        class Specie extends Model
        {
            public function panel() {
                return $this->belongsTo('App\Panel'); 
            }
        }

panel.php

        class Panel extends Model
        {
            protected $guarded  = []; 
            public function species()
            {
                return $this->hasMany('App\Specie', 'panel_id');
            }
        }

index.blade.php

            @extends('layouts.app')
        @section('content')
            <div class="container col-sm-10">
                {!! Form::open(['action' => 'PanelController@store', 'method' => 'POST'])!!}
                <species-overview :speciedata='<?php echo json_encode($species); ?>' 
                ></species-overview>
                {!! Form::close() !!}
            </div>
        @endsection

PanelController.php

          public function store(Request $request)
        {
            $panel = Panel::create([
                'description' =>  $request->description,
                'date' => $request->date
            ]);
            foreach($request->selectedIds as $selectedid){
                $specie = new Specie(['specie_id' => $selectedid]);
                $specie->panel()->assosciate($panel);
                $panel->save();
            }
            return redirect()->route('specie.index')->with('success','Data Added');


        }
Nemo
  • 503
  • 6
  • 23
  • remove ``$panel->save();`` from the loop. Place it after create. And save $specie after creation. – Ivan Klochkov May 22 '19 at 09:28
  • If I do this I got the following error. Invalid argument supplied for foreach(). It seems that my reference to selectedIds is wrong. Would you be able to help? – Nemo May 23 '19 at 07:13
  • Oh, I missed this part. https://laravel.com/docs/5.8/requests#retrieving-input Try ``$selectedIds = $request->input('selectedIds'); foreach($selectedIds as $selectedid) { ....`` but be sure to send array. And make some server-side type checking beforehand. – Ivan Klochkov May 23 '19 at 09:39

1 Answers1

2

I would present the following solution. Instead of HTTP requests using Axios use your form to submit the data to your database. Therefore, you should name yours to submitted values.

 <div class="col-2">
                        <b-form-input v-model="date" class="form-control" type="date" value="getDate" name="date"></b-form-input>
                        <pre class="mt-3 mb-0">{{ date }}</pre>
                    </div>
                    <div class="col-6">
                        <b-form-input v-model="description" placeholder="Enter some text" name="description"></b-form-input>
                        <pre class="mt-3 mb-0">{{ description }}</pre>
                    </div>

For your ids I would present the following:

                        <template slot="name" slot-scope="row" >
                        {{row.item.name}}
                        // Consider this a hidden input field where your ids can be stored in array
                        <input name="species[]" type="hidden" v-model="row.item.id">
                    </template>

It's a many to many relationship. Your panels can contain specie who are presented in diffrent panels. Refer also to your crosstable so laravel will now where to insert your data. This isn't always nesscairy but in some case like.

    public function species()
{
    return $this->belongsToMany('App\Specie', 'antibody_panels','panel_id','specie_id');
}


     public function panel() {
    return $this->belongsToMany('App\Panel','specie_panels','specie_id','panel_id'); 
}

You should use attach when working with many-to-many relations. You can also remove the save(), create automatically saves.

        foreach($selectedIds as $selectedid){
        $panel->species()->attach(Specie::find($selectedid));
    } 

Hope, this helps.

ageans
  • 549
  • 5
  • 20
  • Thanks a lot, So I don't need my functions anymore. What should I do with the controller to insert the data into the database? – Nemo May 24 '19 at 09:48
  • You should remove your functions, Know you are using the form to submit the data. – ageans May 24 '19 at 10:05