Add one to many in form - Backpack laravel
Asked Answered
A

4

18

I'm using Backpack for Laravel to provide the backend area of my laravel website.

I'm having the following tables in my database structure:

enter image description here

This is to add sets to a match, and add matches to a tournament.

These are my Models:

Tournament Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Backpack\CRUD\CrudTrait;

class Tournament extends Model
{
    use CrudTrait;

     /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $fillable = ['from', 'to', 'type', 'location', 'place'];

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */

    public function matches()
    {
        return $this->hasMany('App\Models\Match');
    }
}

Match Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Backpack\CRUD\CrudTrait;

class Match extends Model
{
    use CrudTrait;

     /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'matches';

    protected $fillable = ['opponent'];

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */

    public function sets()
    {
        return $this->hasMany('App\Models\Set');
    }
}

Set Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Backpack\CRUD\CrudTrait;

class Set extends Model
{
    use CrudTrait;

     /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $fillable = ['self', 'opponent', 'index'];

    public function match()
    {
        return $this->belongsTo('App\Models\Match');
    }
}

Now I would like to have the following when I create a Tournament in backend:

enter image description here

I can already set from, to, type, location and place. But now I would like the possibility to add a match and add sets to that match. This all on one page.

But I'm a bit stuck on how to do this. Can someone help me on my way?

Arsine answered 28/2, 2017 at 17:21 Comment(1)
How did you add "add match", "add another match"?Teresa
B
5

I would recommend to all do in multiple steps. Create a tournament, go to tournament view, add matches. Go to a match view, add sets. Wayyyy easier than what you want to do. But hey, it's your application and you want to do in one go.

There are going to be some restrictions like you can only submit one match at a time, to avoid mixing your sets. Unless you want to use javascript and automatically name your matches and sets.

In your models (Match & Set) add foreign keys in the $fillable array. We might need them.

So when you submit the form, you create the tournament

public function save(Request $request)
{
    $tournament = Tournament::create([
        ...
    ]);

    $match = Match::create([
        'tournament_id' => $tournament->id,
        ...
    ]);

    $match->sets()->saveMany([
        new Set(['self' => $request->set1_self, ...]), //foreign key auto inserted
        new Set(['self' => $request->set2_self, ...]),
        new Set(['self' => $request->set3_self, ...]),
    ]);
}

This means in your form, you have to name your sets input like

<input name="set1_self"/>
<input name="set1_opponent"/>

And so on.

Now if you want to make multiple matches at the same time, you will have to find a way to name your inputs like

<input name="match1_set1_self" />
<input name="match1_set2_self" />

And so on.

Since you want to make everything in one page. You can build a mini SPA just to add tournaments, matches & sets. The page won't change/reload.

Bipropellant answered 8/3, 2017 at 5:50 Comment(0)
D
2

Okay so the best is what @EddyTheDove mentioned,

$match->sets()->saveMany([
    new Set(['self' => $request->set1_self, ...]);
    new Set(['self' => $request->set2_self, ...]);
    new Set(['self' => $request->set3_self, ...]);
]);

But it should be done at once via Ajax, And vue.js will be also awesome. Ajax call to create a new tournament, Along fetch all the matches in the same call and attach the selected matches, Again Ajax request to add the matches to the tournament which was created in the earlier Ajax call.

Send the match info in a request to controller via ajax, Where the above code will save it. For more sets, Duplicate the a set html but don't forget the input names. Provide some code that we can play with.

Dalessio answered 9/3, 2017 at 19:24 Comment(1)
Great, An addition, vue.js can make it even more simpler.Panslavism
M
0

You will need to have part of your logic in JavaScript. In your example, when you click the 'Add another match' button you will manipulate the HTML DOM and duplicate the 'Add Match' box.

After filling the whole form, it will get submitted to the server.

The server then needs to:

  1. Create a new Tournament object and save it.

  2. Loop through submitted matches and create new Matches objects and link them to the previously created tournament. Loop through submitted sets and link them to the created match.

Maurene answered 3/3, 2017 at 21:51 Comment(0)
B
0

I think you should design it in such a way that the tournament is created first before the add match/set form is shown. It is still possible to have them all in one form though by applying Ajax or Vue.js etc.

  1. After a new tournament is added successfully, hide the form and display the new tournament info along with the add new match form.

  2. When the new match is added successfully, clear the new match form and load the new match info.

Note: I wonder how you plan to allow the opponent to be added though.

Cheers!

Buprestid answered 6/3, 2017 at 9:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.