2015-10-17 4 views
3

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

У меня есть две таблицы, игроки и команды, а также таблица join players_teams. Форма отображается нормально. Но я хотел бы изменить область выбора в раскрывающемся меню. У игрока может быть много команд с течением времени (я добавил столбцы от и до даты в таблицу соединений для этого), но я хотел бы, чтобы игрок был назначен одной команде в момент ее создания.

Вот что я пробовал:

<?php 
echo $this->Form->input('player_name'); 
     echo $this->Form->input('player_last_name'); 
     echo $this->Form->input('player_number'); 
     echo $this->Form->input('player_birthday'); 
     echo $this->Form->input('teams._ids', [ 'multiple' => false, 'options' => $teams,]); 
    ?> 

Это не меняет к dropdow. Я также попытался это:

echo $this->Form->input('teams._ids', ['type' => 'select', 'multiple' => false, 'options' => $teams, 'empty' => true]); 

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

Heres контроллер для игроков:

public function add() 
{ 
    $player = $this->Players->newEntity(); 
    if ($this->request->is('post')) { 
     $player = $this->Players->patchEntity($player, $this->request->data); 
     if ($this->Players->save($player)) { 
      $this->Flash->success(__('The player has been saved.')); 
      return $this->redirect(['action' => 'index']); 
     } else { 
      $this->Flash->error(__('The player could not be saved. Please, try again.')); 
     } 
    } 
    $teams = $this->Players->Teams->find('list', ['limit' => 200]); 
    $this->set(compact('player', 'teams')); 
    $this->set('_serialize', ['player']); 
} 

Вот PlayersTeamController:

public function add() 
{ 
    $playersTeam = $this->PlayersTeams->newEntity(); 
    if ($this->request->is('post')) { 
     $playersTeam = $this->PlayersTeams->patchEntity($playersTeam, $this->request->data); 
     if ($this->PlayersTeams->save($playersTeam)) { 
      $this->Flash->success(__('The players team has been saved.')); 
      return $this->redirect(['action' => 'index']); 
     } else { 
      $this->Flash->error(__('The players team could not be saved. Please, try again.')); 
     } 
    } 
    $players = $this->PlayersTeams->Players->find('list', ['limit' => 200]); 
    $teams = $this->PlayersTeams->Teams->find('list', ['limit' => 200]); 
    $this->set(compact('playersTeam', 'players', 'teams')); 
    $this->set('_serialize', ['playersTeam']); 
} 

Любая помощь будет очень ценна. Благодаря!

ответ

0

The Cakebook: 3.0

Вы пробовали:

echo $this->Form->select(
    'teams' 
    ,$teams->toArray() 
    ,[ 
    'multiple' => false, 
    'class' => '_ids', 
    'empty' => true 
    ] 
); 
+0

Я получаю это: Ошибка: не может использовать объект типа Cake \ ORM \ Query as array –

+0

@MiguelCedenoAgamez Я ничего не знаю о CakePHP; Я просто быстрый гуглер. извините – Terminus

+0

Не повезло! @Terminus –

0

Просто напоминают требуемая структура данных самостоятельно, то есть

[ 
    'teams' => [ 
     '_ids' => [ 
      // single id here 
     ] 
    ] 
] 

Cookbook > Database Access & ORM > Saving Data > Converting BelongsToMany Data

Proper, array- иш имя

элемента Вы можете сделать это, например, указав соответствующее значение элемента name атрибута, как

echo $this->Form->input(
    'teams', 
    [ 
     'name' => 'teams[_ids][0]' 
     //'options' => $teams // this is optional when following the conventions 
    ] 
); 

, который будет автоматически подобрать select типа, на основе параметров.

Вам понадобится дополнительная логика для предотвращения ввода дополнительных вариантов, так как имя массива, такое как teams[_ids][0], позволило бы, если бы компонент безопасности не смог обнаружить такое вмешательство. Это можно сделать с помощью валидации или путем подготовки данных в событии Model.beforeMarshal.

Вот пример проверки

public function validationCreate(Validator $validator) { 
    $validator = $this->validationDefault($validator); 

    $teamsValidator = (new Validator()) 
     ->requirePresence('_ids') 
     ->notEmpty('_ids') 
     ->add('_ids', 'valid', [ 
      'rule' => function($value) { 
       return is_array($value) && count($value) === 1; 
      } 
     ]); 

    $validator 
     ->requirePresence('teams') 
     ->notEmpty('teams') 
     ->addNested('teams', $tagsValidator); 

    return $validator; 
} 
$player = $this->Players->patchEntity($player, $this->request->data, [ 
    'validate' => 'create' 
]); 

на заказ, одно значение имени элемента

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

echo $this->Form->input('teams', ['name' => 'initial_team']); 
public function beforeMarshal(Event $event, \ArrayObject $data, \ArrayObject $options) 
{ 
    if (isset($data['initial_team'])) { 
     $data['teams'] = [ 
      '_ids' => [ 
       $data['initial_team'] 
      ] 
     ]; 
    } 
} 

Cookbook > Database Access & ORM > Saving Data > Modifying Request Data Before Building Entities

Примечание

Оба сохраняют магию CakePHP, как маршаллер, преобразующий прошедшие _ids в объекты, чтобы ассоциации сохранялись правильно, автоматически выбирали параметры ввода, автоматически выбирали тип ввода и т. Д.

0

Если вы сделали associations, вы можете сохранить его непосредственно с PlayersController. PlayersTeamController вообще не нужен. Когда вы исправляете вновь созданного игрока entity с данными запроса, соответствующие данные таблицы будут автоматически попадать в него и сохраняться командой save() как только один уровень ассоциации.

Смежные вопросы