2013-11-07 3 views
1

У нас есть две модели, которые связаны с has и принадлежат многим отношениям (HABTM): Jobs, Tests. Мы можем успешно добавлять/редактировать отношения (мы знаем, потому что они отображаются в таблице соединений), но мы не можем получить существующие значения в представлении. Флажки select/check (мы пробовали оба) всегда пусты.CakePHP: FormHelper, не отображающий значения по умолчанию из связанной модели

Вот модель отношений:

//Job.php 
public $hasAndBelongsToMany = array (
    'Test' => array (
     'classname' => 'Test', 
     'foreignKey'=>'job_id', 
     'joinTable' => 'jobs_tests', 
     'associatedForeignKey' => 'test_id' 
    ) 
); 

//Test.php 
    public $hasAndBelongsToMany = array(
     'Job' => array(
      'className'=> 'Job', 
      'joinTable'=>'jobs_tests', 
      'foreignKey' => 'test_id', 
      'associatedForeignKey'=> 'job_id' 
      ) 

    ); 

Здесь вы /view/Jobs/edit.ctp

  echo $this->Form->select('Test', $test_options, array('class'=>'form-control', 'multiple'=>'checkbox')); 
//This is always empty (nothing selected/checked). 

Что мы делаем не так?

Update:

Вот JobsController действие:

public function admin_edit($id=NULL) { 
    $this->layout = 'admin'; 
    if (!$id) 
     $this->redirect(array('controller'=>'jobs', 'action'=>'index')); 

    $this->loadModel('Company'); 
    $companies = $this->Company->find('all'); 
    $company_options = array(); 
    foreach ($companies as $company) { 
     $company_options[ $company['Company']['id'] ] = $company['Company']['name']; 
    } 
    $this->set('company_options', $company_options); 

    $this->loadModel('Test'); 
    $tests = $this->Test->find('all'); 
    $tests_options = array(); 
    foreach ($tests as $test) { 
     $test_options[ $test['Test']['id'] ] = $test['Test']['name']; 
    } 
    $this->set('test_options', $test_options); 

    $category_options = $this->Job->validCategories; 

    $this->set('category_options', $category_options); 

    if ($this->request->isPut()) { 
     $data = $this->request->data; 
     //debug($data);exit; 
     $save = $this->Job->save($data); 
     if ($save) { 
      $this->Session->setFlash('Job edited'); 
      //$job = $this->Job->findById($id); 
     } else { 
      $this->Session->setFlash('Error editting job'); 
     } 


    } 

    $job = $this->Job->findById($id); 
    $this->request->data = $job; 
    $this->set('job', $job); 
} 

Вот форма в представлении admin_edit.ctp:

<?php echo $this->Form->create('Job'); ?> 
    <fieldset> 
     <?php 
      echo $this->Form->input('id', array('type'=>'hidden')); 
      echo $this->Form->input('name', array('class'=>'form-control')); 
      echo $this->Form->input('email', array('class'=>'form-control')); 
      echo $this->Form->input('location', array('class'=>'form-control')); 

      echo '<label>Type</label>'; 
      echo $this->Form->select('type', array('FT'=>'Full Time', 'PT'=>'Part Time', 'IN'=>'Internship'), array('empty'=>false, 'class'=>'form-control')); 

      echo '<label>Company</label>'; 
      echo $this->Form->select('company_id', $company_options, array('class'=>'form-control')); 
      echo $this->Form->input('short_description', array('label' => 'Short Description', 'class'=>'form-control')); 
      echo $this->Form->input('full_description', array('type'=>'textarea', 'label' => 'Full Description', 'class'=>'form-control')); 
      echo $this->Form->input('is_private', array('label'=>'Is Private?', 'class'=>'form-control')); 

      echo '<label>Category</label>'; 
      echo $this->Form->select('category', $category_options, array('class'=>'form-control')); 
      echo '<label>Tests</label>';    
      //echo $this->Form->select('Test.id', $test_options, array('class'=>'form-control', 'multiple'=>true)); 

      $selected = array(); 
      foreach ($job['Test'] as $test) { 
       $selected[]=$test['id']; 
       //$selected[ $test['id'] ] = $test['name']; 
      } 
      debug($selected); 
      echo $this->Form->input('Test', array('type'=>'select', 'options'=>$test_options, 'class'=>'form-control', 'multiple'=>'checkbox', 'selected'=>$selected)); 
     ?> 
    </fieldset> 
    <?php echo $this->Form->end(__('Submit')); ?> 
+0

На стороне примечание, это 'associationForeignKey', а не' associatedForeignKey', но нет необходимости определять эти значения при выполнении соглашений, так как CakePHP автоматически выбирает правильные имена. – ndm

+0

Помимо того, что вы делаете свой путь жизни более сложным, чем необходимо, и это всегда будет потерять ваш вход, если форма не может быть сохранена, поскольку вы всегда ее перезаписываете (возможно, это ваша проблема?) Потеря выбора после отправки форма?), я не понимаю, почему это не должно работать, предполагая, что '$ test_data' и' $ selected' содержат ожидаемые данные. При этом было бы полезно посмотреть, что именно они содержат. – ndm

+0

@ndm Пример $ test_data: 'массив ( \t (INT) 0 => '5', \t (целое) 1 => '7' ) '. Данные не теряются после подачи. Значения по умолчанию/текущий все отображаются в порядке. Проблемно только ассоциация HABTM. – emersonthis

ответ

2

PHEW! Это было потрясающе, но решение оказалось простым ... Значения в $ options ['selected'] были строками (чисел), что путало CakePHP. Мы превратили их в Интс, используя intval() и она прекрасно работает сейчас, используя все первоначальные настройки ...

Вот пересмотренная версия о том, что в представлении (обратите внимание на intval()):

 $selected = array(); 
     foreach ($job['Test'] as $test) { 
      $selected[]= intval($test['id']); 
     } 
     echo $this->Form->input('Test', array('type'=>'select', 'options'=>$test_options, 'class'=>'form-control', 'multiple'=>'checkbox', 'selected'=>$selected)); 

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

  1. $options['selected'] делает не должны быть ключевыми => парами значений.
  2. Образец, который мы используем, не перезаписывает запрос-> данные и передает данные в хелпер просто отлично.
  3. имена переменных non-camelCased, переданные в представление ($ some_variable_name), по-прежнему правильно обрабатываются помощником формы.

Надеюсь, это пригодится кому-то еще.

+0

** 1. ** Никто не сказал, что это будет так, конечно, это параметры данных, которые должны быть в формате 'key => value'. ** 2. ** Это _does_ by '$ this-> request-> data = $ job;', и в случае, если данные не могут быть сохранены, вы потеряете свой вход, поскольку он будет перезаписан данными, извлеченными из БД. ** 3. ** Никто не пытался доказать обратное ...хотя это не совсем так, как есть, вы можете _explicitly_ передать любую переменную, которую хотите использовать хелперу Form, но переменные вида _auto-pickup_, принадлежащие к 'hasMany' /' HABTM', связаны с соответствующими именами переменных множественного числа верблюдов. – ndm

+0

Это все, что вы описали в # 3 в моем коде? – emersonthis

+0

Не все, но некоторые из них, да. Вы явно передаете переменные вида в помощник формы, что в вашем случае необходимо, поскольку оно не будет автоматически подбирать его, поскольку это потребует соблюдения указанных соглашений об именах. – ndm

0

Что делать, если вы пройти множество по умолчанию значения с помощью Model :: find ('list').

//controller 
$this->set('test_options', $this->YourModel->find('list')); 


//view 
echo $this->Form->select('Test', $test_options, array('class'=>'form-control', 'multiple'=>'checkbox')); 
+0

Да. Это будет работать, но это немного «аналог». Помимо хлопот при ручной настройке значений по умолчанию, я обеспокоен тем, что это подразумевает что-то не так с нашими ассоциациями моделей. PS: Я думаю, вы пропустили массив «values» => ... в своем коде. – emersonthis

+0

@Emerson В этом нет ничего плохого, фактически вы _must_ передаете значения в представление, CakePHP не сделает это автоматически для вас. Но при этом вы должны придерживаться условных обозначений, а это значит, задайте значения в переменной с наименьшим именем модели множественного числа, то есть 'tests', и используйте' FormHelper :: input() ', таким образом, помощник формы может забрать данные и автоматически проверить необходимые значения. См. Http://book.cakephp.org/2.0/ru/models/saving-your-data.html#saving-related-model-data-habtm – ndm

+0

@GuillemoMansilla Возможно, вы захотите соответствующим образом обновить свой ответ. – ndm

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