Добавить один ко многим в форме-рюкзак laravel

Я использую рюкзак для Laravel обеспечить внутренние области Мой сайт Laravel.

у меня есть следующее таблицы в моей структуре базы данных:

enter image description here

Это для добавления наборов в матч и добавления матчей в турнир.

мои модели:

Модель Турнира:

<?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;
use BackpackCRUDCrudTrait;

class Tournament extends Model
{
    use CrudTrait;

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

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

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

    public function matches()
    {
        return $this->hasMany('AppModelsMatch');
    }
}

матч Модель:

<?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;
use BackpackCRUDCrudTrait;

class Match extends Model
{
    use CrudTrait;

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

    protected $table = 'matches';

    protected $fillable = ['opponent'];

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

    public function sets()
    {
        return $this->hasMany('AppModelsSet');
    }
}

Модель:

<?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;
use BackpackCRUDCrudTrait;

class Set extends Model
{
    use CrudTrait;

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

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

    public function match()
    {
        return $this->belongsTo('AppModelsMatch');
    }
}

Теперь я хотел бы иметь следующее, Когда я создаю турнир в бэкэнде:

enter image description here

Я уже могу установить От, До, тип, местоположение и место. Но теперь я хотел бы иметь возможность добавить матч и добавить наборы к этому матчу. Все это на одной странице.

но я немного застрял на том, как это сделать. Кто-нибудь может мне помочь?

4 ответов


Я бы рекомендовал все делать в несколько шагов. Создайте турнир, перейдите в турнирный вид, добавьте матчи. Перейдите к представлению соответствия, добавьте наборы. Это проще, чем то, что ты хочешь сделать. Но эй, это ваше приложение, и вы хотите сделать это за один раз.

будут некоторые ограничения, как вы можете отправить только один матч за раз, чтобы избежать смешивания ваших наборов. Если вы не хотите использовать javascript и автоматически называть свои матчи и наборы.

в ваших моделях (матч & Set) добавить внешние ключи в $fillable массив. Они могут нам понадобиться.

поэтому, когда вы отправляете форму, вы создаете турнир

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, ...]),
    ]);
}

Это означает, что в вашей форме, вы должны назвать свой входных наборов, как

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

и так далее.

теперь, если вы хотите сделать несколько совпадений одновременно, вам нужно будет найти способ назвать свои входы как

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

и так далее.

поскольку вы хотите сделать все на одной странице. Вы можете построить мини-СПА, чтобы добавить турниры, матчи и наборы. Страница не будет меняться / перезагружаться.


хорошо, поэтому лучше всего то, что @EddyTheDove упомянул,

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

но это должно быть сделано сразу через Ajax и vue.js также будет потрясающим. Ajax вызов, чтобы создать новый турнир, наряду получить все матчи в том же вызове и прикрепить выбранные матчи, снова Ajax запрос, чтобы добавить матчи в турнир, который был создан в предыдущем вызове Ajax.

отправьте информацию о матче в запросе контроллеру через ajax, где приведенный выше код сохранит его. Дополнительные наборы, Дублируйте набор html, но не забывайте имена входных данных. Предоставьте код, с которым мы можем играть.


вам нужно будет иметь часть вашей логики в JavaScript. В вашем примере, когда вы нажимаете кнопку "Добавить другое совпадение", вы будете управлять HTML DOM и дублировать поле "Добавить совпадение".

после заполнения всей формы она будет отправлена на сервер.

затем сервер должен:

  1. создайте новый объект турнира и сохраните его.

  2. цикл через отправленные матчи и создавать новые объекты матчей и связать их с ранее созданным турниром. Цикл через отправленные наборы и связать их с созданным совпадением.


Я думаю, вы должны спроектировать его таким образом, чтобы турнир был создан первым, прежде чем будет показана форма добавить матч/набор. По-прежнему можно иметь их все в одной форме, хотя с помощью Ajax или Vue.Яш и т. д.

  1. после успешного добавления нового турнира скройте форму и отобразите новую информацию о турнире вместе с формой добавления нового матча.

  2. при успешном добавлении нового соответствия очистите новую форму соответствия и загрузите новый матч.

Примечание: интересно, как вы планируете позволить противнику быть добавлены, хотя.

Ура!