BACKPACK Laravel управляет дополнительными столбцами в сводной таблице в отношениях «многие ко многим» с помощью Backpack CRUD - PullRequest
1 голос
/ 07 июня 2019

Я использую рюкзак для laravel, и я пытаюсь добавить / обновить некоторые дополнительные столбцы в сводной таблице, используемой в отношениях «многие ко многим».

Подводя итог контексту: у меня есть модель Задача , другая модель Машина и эта промежуточная сводная таблица machine_task , содержащая многие ко многимотношение между задачей и машиной

В этой задаче machine_task есть machine_id , task_id , а затем логические столбцы m (для «ежемесячных»), q (для «квартальных»), b (для «двухгодичных») и y (для «годовых»).

Вот чтоУ меня

В моих Models / Task.php я определил отношение m-2-m


   public function machines()
    {
        return $this->belongsToMany('App\Machine')->withPivot('m','q','b','y');
    }

In / app / Http /Controllers / Admin / TaskCrudController.php У меня есть поля, наиболее релевантным из которых является

       $this->crud->addField([   // n-n relationship
           'label' => "Machines", // Table column heading
           'type' => "select2_from_ajax_multiple_custom", // a customized field type modifying the standard select2_from_ajax_multiple type
           'name' => 'machines', // the column that contains the ID of that connected entity
           'entity' => 'machines', // the method that defines the relationship in your Model
           'attribute' => "name", // foreign key attribute that is shown to user
           'model' => "App\Models\Machine", // foreign key model
           'data_source' => url("api/machines"), // url to controller search function (with /{id} should return model)
           'placeholder' => "Select machine(s)", 
           'minimum_input_length' => 0, 
           'pivot' => true, 

           'dependencies' => ['building_id'], // this "Machines" field depends on another previous field value
           ]);

. Это прекрасно работает: когда я создаю или обновляю задачу, выполняется вызов AJAX, возвращающий праворезультаты, значения правильно добавляются во входные данные select2, а сводная таблица machine_task правильно заполнена и обновлена ​​с помощью task_id и machine_id когда я нажимаю на кнопку Сохранить и вернуться.

Но как вставить в сводную таблицу дополнительные значения m , q , b , y вместе с task_id и machine_id ?

В конце TaskCrudController.php У меня есть

 public function store(StoreRequest $request)
    {
        // your additional operations before save here
        // What I should do here to get the pivot values into the request??????????????
        $redirect_location = parent::storeCrud($request);
        // your additional operations after save here
        // use $this->data['entry'] or $this->crud->entry
        return $redirect_location;
    }

    public function update(UpdateRequest $request)
    {
        // your additional operations before save here
        // What I should do here to get the pivot values into the request??????????????
        $redirect_location = parent::updateCrud($request);     
        // your additional operations after save here
        // use $this->data['entry'] or $this->crud->entry
        return $redirect_location;
    }

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

select2_from_ajax_multiple_custom

В / vendor / backpack / crud / src / resources / views / fields / select2_from_ajax_multiple_custom.blade.php Я инициализирую подобные значения, а затем использую jquery для обновления строк, синхронизированных с элементом управления select2, но я не знаю, как связать флажки m, q, b, y с каждым из выбранных select2варианты и передать их на запрос.

    @if ($old_value)
            @foreach ($old_value as $item)
                @if (!is_object($item))
                    @php
                        $item = $connected_entity->find($item);
                    @endphp
                @endif
                <div id="div{{ $item->getKey() }}">
                <span> {{ $item->getKey() }} {{ $item->{$field['attribute']} }} -- </span>
                Monthly <input type="checkbox" id="m{{ $item->getKey() }}" name="m{{ $item->getKey() }}" value="1" @php if ($item->pivot['m'] == "1") echo "checked"; @endphp > 
                Quarterly <input type="checkbox" id="q{{ $item->getKey() }}" name="q{{ $item->getKey() }}" value="1" @php if ($item->pivot['q'] == "1") echo "checked"; @endphp> 
                Biannual <input type="checkbox" id="b{{ $item->getKey() }}" name="b{{ $item->getKey() }}" value="1" @php if ($item->pivot['b'] == "1") echo "checked"; @endphp> 
                Yearly <input type="checkbox" id="y{{ $item->getKey() }}" name="y{{ $item->getKey() }}"value="1" @php if ($item->pivot['y'] == "1") echo "checked"; @endphp> <br/>
                @php
                @endphp
                </div>
            @endforeach
        @endif

Большое спасибо заранее за ваше время, и я надеюсь, что вы можете мне помочь!Кинда застряла с этим!

1 Ответ

2 голосов
/ 08 июня 2019

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

То, что я сделал,

В моем TaskCrudController.php Я добавил базовую модель задач

// add this to the use statements 
use App\Models\Task;

, затем также в TaskCrudController.php Я сделал это

// Notice: You need to add this to "create" function as well, I'm just writing here the update function to keep it short.
 public function update(UpdateRequest $request)
    {
$redirect_location = parent::updateCrud($request);
foreach ($request->machines as $machine) {
            $set= array('m'=>'0','t'=> '0', 's' => '0', 'a' => '0');
            if (isset($request['m'])) in_array ($machine, $request['m']) ? $set['m'] = '1' :  $set['m'] = '0';
            if (isset($request['t'])) in_array ($machine, $request['t']) ? $set['q'] = '1' :  $set['q'] = '0';
            if (isset($request['s'])) in_array ($machine, $request['s']) ? $set['b'] = '1' :  $set['b'] = '0';
            if (isset($request['a'])) in_array ($machine, $request['a']) ? $set['y'] = '1' :  $set['y'] = '0';

            Task::find($request->id)->machines()->syncWithoutDetaching([$machine => $set]);
return $redirect_location;
        }

// Code explanation:
// what we are doing basically here is to grab the $request data
// For example: In the $request we receive m[3] b[1,3] y[1] arrays
// meaning that for our task:
// Machine 1 has no monthly, no quarterly but biannual and yearly checkboxes checked
// Machine 3 has monthly, no quarterly, biannual and no yearly checkboxes checked
// with the loop above, we cast that incoming data into this structure
// $set would contain after the loop:
// '1' => ['m' => '0', 'q'=> '0', 'b' => '1', 'y' => '1']
// '3' => ['m' => '1', 'q'=> '0', 'b' => '1', 'y' => '0']

// with that, we updated the intermediate table using syncWithoutDetaching

Теперь давайте посмотрим select2_from_ajax_multiple_custom.blade.php хотя я не публикую весь код (остальное то же самое, что стандартное поле select2_from_ajax_multiple)

<div @include('crud::inc.field_wrapper_attributes') >
   <label>{!! $field['label'] !!}</label>
   @include('crud::inc.field_translatable_icon')
   <select
       name="{{ $field['name'] }}[]"
       style="width: 100%"
       id="select2_ajax_multiple_custom_{{ $field['name'] }}"
       @include('crud::inc.field_attributes', ['default_class' =>  'form-control'])
       multiple>

       @if ($old_value)
           @foreach ($old_value as $item)
               @if (!is_object($item))
                   @php
                       $item = $connected_entity->find($item);
                   @endphp
               @endif
               <option value="{{ $item->getKey() }}" selected>
                   {{ $item->{$field['attribute']} }}
               </option>
           @endforeach
       @endif
   </select>
// What I added is:
   <div id="freq">
   @if ($old_value)
           @foreach ($old_value as $item)
               @if (!is_object($item))
                   @php
                       $item = $connected_entity->find($item);
                   @endphp
               @endif
               <div id="div{{ $item->getKey() }}">
               <span>{{ $item->{$field['attribute']} }} -- </span>
               Monthly <input type="checkbox" id="m{{ $item->getKey() }}" name="m[]" value="{{ $item->getKey() }}" @php if ($item->pivot['m'] == "1") echo "checked"; @endphp > 
               Quarterly <input type="checkbox" id="q{{ $item->getKey() }}" name="q[]" value="{{ $item->getKey() }}" @php if ($item->pivot['q'] == "1") echo "checked"; @endphp> 
               Biannual <input type="checkbox" id="b{{ $item->getKey() }}" name="b[]" value="{{ $item->getKey() }}" @php if ($item->pivot['b'] == "1") echo "checked"; @endphp> 
               Yearly <input type="checkbox" id="y{{ $item->getKey() }}" name="y[]"value="{{ $item->getKey() }}" @php if ($item->pivot['y'] == "1") echo "checked"; @endphp> <br/>

               </div>
           @endforeach
       @endif
   </div>


// js code to add or remove rows containing the checkboxes (This needs to be put inside <script> tags obviously)    $("#select2_ajax_multiple_custom_machines").on("select2:select", function(e) {
// add checkbox row
           htmlRow = "<div id=\"div"+e.params.data.id+"\">"+"<span> "+e.params.data.text+"-- </span>"+" Monthly <input type=\"checkbox\" id=\"m"+e.params.data.id+"\" name=\"m[]\" value=\""+e.params.data.id+"\">";
           htmlRow += " Quarterly <input type=\"checkbox\" id=\"q"+e.params.data.id+"\" name=\"q[]\" value=\""+e.params.data.id+"\">";
           htmlRow += " Biannual <input type=\"checkbox\" id=\"b"+e.params.data.id+"\" name=\"b[]\" value=\""+e.params.data.id+"\">";
           htmlRow += " Yearly <input type=\"checkbox\" id=\"y"+e.params.data.id+"\" name=\"y[]\" value=\""+e.params.data.id+"\"><br/>";
           htmlRow += "</div>";
           $("#freq").append(htmlRow);  
       });

$("#select2_ajax_multiple_custom_machines").on("select2:unselect", function(e) {
// remove checkbox row
           $("#div"+e.params.data.id).remove(); 
});

И все, ребята.Надеюсь, это поможет.

...