Сохранение дополнительных данных в общую таблицу в CakePHP 3.0

Я пытаюсь сохранить некоторые данные в объединенную таблицу, используя CakePHP. Вот эту часть приложения я и хотел бы исправить — это обычная ассоциация BelongsToMany с дополнительными колонками:

Модель > Сущность:

/* Durations */
class Duration extends Entity {
  protected $_accessible = [
    'duration' => true,
    'cost' => true,
  ];
}

/* Commercials */
class Commercial extends Entity {

  protected $_accessible = [
    'info' => true,
    'commercial_durations' => true,
  ];
}

/* CommercialDurations */
class CommercialDuration extends Entity {
  protected $_accessible = [
    'duration_id' => true,
    'commercial_id' => true,
    'quantity' => true,
    'duration' => true,
    'commercial' => true,
  ];
}

Модель > Таблица:

class DurationsTable extends Table {
  public function initialize(array $config)
  {
    $this->table('durations');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->belongsToMany('Commercials', [
        'through' => 'CommercialDurations',
    ]);
  }
}

class CommercialsTable extends Table
{
  public function initialize(array $config){
    $this->table('commercials');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->belongsToMany('Durations', [
        'through' => 'CommercialDurations'
    ]);

    $this->hasMany('CommercialDurations', [
        'foreignKey' => 'commercial_id'
    ]);

  }
}

class CommercialDurationsTable extends Table {
  public function initialize(array $config)
  {
    $this->table('commercial_durations');
    $this->displayField('id');
    $this->primaryKey('id');
    $this->belongsTo('Durations', [
        'foreignKey' => 'duration_id',
        'joinType' => 'INNER'
    ]);
    $this->belongsTo('Commercials', [
        'foreignKey' => 'commercial_id',
        'joinType' => 'INNER'
    ]);
  }
}

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

<?php 
  echo $this->Form->create($commercial); 
    echo $this->Form->input('durations._duration', ['options' => $durations]);
    echo $this->Form->input('durations._joinData.quantity'); 
    echo $this->Form->submit(__('Next'), ['class' => 'button small right', 'escape' => false]);
  echo $this->Form->end() 
?>

Проблема с этой формой заключается в том, что при выборе длительности не отображается поле «длительность» из таблицы «Длительности», а вместо этого отображаются все поля из этой таблицы (по одному на строку) в формате JSON.

<option value="0">{ "id": 1, "duration": "30 sec", "cost": 450 }</option>

После отправки формы я не могу сохранить эту информацию в объекте Commercials или в CommercialDurations. Вот что я получаю от объекта $this->request->data:

[
'durations' => [
    '_duration' => '2',
    '_joinData' => [
        'quantity' => '2'
    ]
  ] 
]

Вывод debug((string)$commercial) до запуска формы:

/src/Template/Commercials/features.ctp (line 22)
'{
  "id": 2,
  "info": "AAAAAA ",
  "created": "2015-04-16T21:48:48+0000",
  "updated": null,
  "durations": [],
}'

Как правильно отобразить данные на форме? Как я могу получить и сохранить эти данные?

Спасибо!!


person jpruizs    schedule 20.04.2015    source источник
comment
Пожалуйста, покажите результат debug((string)$commercial) перед вызовом $this->Form->create($commercial)   -  person José Lorenzo Rodríguez    schedule 22.04.2015
comment
@JoséLorenzo Я добавил эту информацию к исходному вопросу. Спасибо.   -  person jpruizs    schedule 22.04.2015
comment
Откуда нам { "id": 1, "duration": "30 sec", "cost": 450 }? В вашей сущности нет ничего о durations   -  person José Lorenzo Rodríguez    schedule 23.04.2015
comment
Я думаю, вы правы, @JoséLorenzo вместо «commercial_durations» =› true я добавил «durations» =› true, . Спасибо! Я добавлю полный ответ ниже   -  person jpruizs    schedule 25.04.2015


Ответы (1)


Я не понимаю ваших отношений с моделями, поскольку, согласно вашему сообщению, продолжительность принадлежит рекламе, а реклама принадлежит продолжительности.

Чтобы объяснить вам, как должен быть отправлен запрос и как выглядит форма, давайте предположим для этого примера, что ваши модели такие:

Ваша реклама имеет коммерческую продолжительность, и эта рекламная продолжительность относится к продолжительности

Таким образом, ваши модели будут выглядеть так:

  • Коммерческий имеет много коммерческой продолжительности.

  • Коммерческая продолжительность относится к рекламной.

  • Коммерческая продолжительность принадлежит длительности.

  • Продолжительность имеет много коммерческой продолжительности.

Ваша функция добавления должна быть похожа на эту (при условии, что вы не сохраняете новую продолжительность, а только рекламу и продолжительность рекламы)

    $commercial = $this->Commercials->newEntity($this->request->data,[
        'associated' => ['Commercialdurations']
    ]);
    if ($this->Commercials->save($commercial)) {
    $success = true;
    }else{
    $success = false;
    }

Данные запроса должны выглядеть так:

{  
   "commercialdurations":{  
      "Commercialduration":{
      "duration_id":"1",
      "quantity":"1",
      "duration":"1"  
      }
   },
   "info":"something"
}

По сути, вы отправляете данные новой рекламы (информация) и связанные с ней рекламные продолжительности (вы можете отправить несколько рекламных продолжительностей).

Чтобы ваша форма отображала продолжительность, в основном вы должны сериализовать эту информацию в контроллере, перейти к действию добавления и добавить это. (Вы можете использовать все, что хотите, чтобы получить данные, все, что имеет значение, это то, что вы отправляете их обратно в представление)

    $durations = $this->Commercials->Commercialdurations->Durations->find('list', ['limit' => 200]);
    $this->set(compact('commercial',durations'));
    $this->set('_serialize', ['commercial']);

Затем в вашей форме вы можете использовать данные

echo $this->Form->input('duration_id', ['options' => $durations]);

Таким образом, ваша форма будет выглядеть примерно так:

    echo $this->Form->input('info');
    echo $this->Form->input('commercials.Commercial.duration_id', ['options' => $durations]);
    echo $this->Form->input('commercials.Commercial.quantity');
    echo $this->Form->input('commercials.Commercial.duration');

В основном вы хотите отправить запрос со всеми уровнями связанных данных.

См. этот другой вопрос для руководства по сохранению связанных данных:

Cake PhP 3 Сохранение связанных данных на нескольких уровнях< /а>

Чтобы узнать больше о том, как создать форму:

http://book.cakephp.org/3.0/en/views/helpers/form.html#creating-inputs-for-associated-data

person Danny Sandi    schedule 13.07.2015