Как заполнить параметры в элементе управления формой из третьей таблицы в "edit.ctp" в CakePHP 3. X?


у меня есть три таблицы (локали ,маршруты и расписания):

Локальная Таблица:

   id   |   nombreLocal
--------------------------
    1       Local Uno
    2       Local Dos
    3       Local Tres

Таблица Пути:

   id   |   id_local_origen   |   id_local_destino
--------------------------------------------------
    1             1                    2
    2             2                    3

Таблица Расписаний:

   id   |   id_rutas
---------------------
    1          1
    2          2

у меня есть следующие ассоциации:

в локальной таблице:

$this->hasMany('Rutas', [
    'foreignKey' => 'id_local_origen'
]);

 $this->hasMany('Rutas', [
    'foreignKey' => 'id_local_destino'
]);

в таблице пути:

$this->belongsTo('Origen', [
    'foreignKey' => 'id_local_origen',
    'className' => 'Locales',
    'joinType' => 'INNER'
]);
$this->belongsTo('Destino', [
    'foreignKey' => 'id_local_destino',
    'className' => 'Locales',
    'joinType' => 'INNER'
]);

$this->hasMany('Programaciones', [
    'foreignKey' => 'id_rutas'
]);

в таблице расписания:

$this->belongsTo('Rutas', [
    'foreignKey' => 'id_rutas',
    'joinType' => 'INNER'
]);

Мне нужно решить

в edit. ctp расписаний должно что-то выйти так:

Esto es el template de edit.ctp de la tabla programaciones

в обработчике расписания у меня есть следующее в действии Edit:

public function edit($id = null)
{
    $programacione = $this->Programaciones->get($id, [
        'contain' => []
    ]);
    if ($this->request->is(['patch', 'post', 'put'])) {
        $programacione = $this->Programaciones->patchEntity($programacione, $this->request->getData());
        if ($this->Programaciones->save($programacione)) {
            $this->Flash->success(__('The programacione has been saved.'));

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('The programacione could not be saved. Please, try again.'));
    }
    $this->set(compact('programacione'));



    // Enviando rutas
    $tabla_rutas = TableRegistry::get('Rutas');
    $query = $tabla_rutas->find('list', [
                'keyField' => 'id_rutas',
                'valueField' => ['id_local_origen','id_local_destino']
            ]);
    $rutas = $query->toArray();
    $this->set(compact('rutas', $rutas));
    debug($rutas);
}

в debug я получаю это:

[
    (int) 1 => '1;2',
    (int) 2 => '2;3'
]
 1
Author: CARLOS B., 2018-06-10

1 answers

Для этого случая мы можем объявить virtual property в Entity.

Для этого мы добавляем функцию _getRutaName() внутри класса Path

Ruta.php

public function _getRutaName()
{
    $rutaName = '';

    if (
        !empty($this->_properties['origen']->nombreLocal) &&
        !empty($this->_properties['destino']->nombreLocal)
    ) {
        $rutaName = $this->_properties['origen']->nombreLocal . ' - ' .
                $this->_properties['destino']->nombreLocal;
    }

    return $rutaName;
}

В Table Мы должны сказать вам, что ваш displayField является новым виртуальным свойством, которое мы только что объявили, следуя соглашениям CakePHP, это будет имя с "underscore"

В RutasTable.php

$this->setDisplayField('ruta_name');

И, наконец, в контроллере мы вызываем массив, который мы развернем в наше представление важно чтобы с помощью магии query builder CakePHP мы вызывали contain с источником и целью, чтобы они существовали в $this->_properties в Entity.

Параметрам find мы передадим в качестве аргументов 'keyField' => 'id' с идентификатором пути для сохранения и с 'valueField' => 'ruta_name' с нашим новым virtualField

ProgramacionesController.php

public function edit($id = null)
{
    $programacione = $this->Programaciones->get($id, [
        'contain' => []
    ]);
    if ($this->request->is(['patch', 'post', 'put'])) {
        $programacione = $this->Programaciones->patchEntity($programacione, $this->request->getData());
        if ($this->Programaciones->save($programacione)) {
            $this->Flash->success(__('The programacione has been saved.'));

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('The programacione could not be saved. Please, try again.'));
    }

    $query = $this->Programaciones->Rutas->find('list', [
        'keyField' => 'id',
        'valueField' => 'ruta_name'
    ])->contain(['Origen', 'Destino']);
    $rutas = $query->toArray();

    $this->set(compact('programacione', 'rutas'));
}

Наконец, в представлении мы обычно называем, как мы делали раньше с магия FormHelper CakePHP, я предлагаю удалить параметр 'empty' => true , так как если он будет выбран, он добавит как id 0, что приведет к неожиданным результатам

<?= $this->Form->control('id_rutas', ['options' => $rutas, 'empty' => true]) ?>

Это приведет к чему-то похожему на это:

<div class="input select"><label for="id-rutas">Id Rutas</label>
  <select name="id_rutas" id="id-rutas">
    <option value=""></option>
    <option value="1" selected="selected">Local uno - Local dos</option>
    <option value="2">Local dos - Local tres</option>
  </select>
</div>
 1
Author: , 2018-06-10 04:32:33