CGridview и Yii Active Record Relation - PullRequest
       25

CGridview и Yii Active Record Relation

3 голосов
/ 13 января 2012

У меня есть две таблицы tbl_business и business_contacts следующей структуры:

  tbl_business
  ---
  business_id (PK)
  othercolumns

и

  business_contacts
  ---
  contact_id (PK)
  business_id 
  othercolumns

Сценарий состоит в том, что в одной бизнес-строке много контактов. Я использую cGridview с использованием генератора CRUD от gii, и мне нужно было отобразить имя и фамилию из business_contacts (одна из нескольких возможных строк в таблице) для каждой записи tbl_business.

Насколько я понимаю, я обновил функцию отношения в модели tbl_business:

  'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname')

и для этого же контактное отношение определяется в модели business_contacts как:

  'contactbusiness' => array(self::BELONGS_TO,'BusinessContact','business_id')

Я ожидал, что это сработает для извлечения связанных записей, так что у меня может быть что-то в сетке, например, business_id, contact_firstname, contact_lastname, ... otherbusinesstablecolumns .. но я получаю только пустые значения под именем и фамилией .. может кто-нибудь, пожалуйста, помогите мне понять ошибку? (

Ответы [ 2 ]

4 голосов
/ 13 января 2012

Итак, вы пытаетесь отобразить таблицу предприятий (tbl_business), используя CGridView? И в каждой строке Бизнеса вы хотите перечислить несколько контактов (business_contacts)?

CGridView не поддерживает отображение отношений HAS_MANY по умолчанию. CGridView позволяет легко перечислить, какой Business a Contact BELONGS_TO (т. Е. Вы можете использовать имя столбца, например contactbusiness.business_id), но , а не все контакты, которые находятся в бизнесе.

Вы можете сделать это самостоятельно, настроив CDataColumn. ( Примечание : это не позволит вам отсортировать и отфильтровать столбец, просто посмотрите. Вам придется проделать гораздо больше работы, чтобы заставить их работать.)

Сначала в вашей бизнес-модели добавьте такой метод, чтобы распечатать все контакты:

public function contactsToString() {
  $return = '';
  foreach ($this->businesscontacts as $contact) {
    $return .= $contact->contact_firstname.' '.$contact->contact_firstname.'<br />';
  }
  return $return;
}

( РЕДАКТИРОВАТЬ: Или сделать это, чтобы распечатать только первый контакт):

public function contactsToString() {
  if($firstContact = array_shift($this->businesscontacts)) {
    return $firstContact->contact_firstname.' '.$firstContact->contact_firstname;
  }
  return '';
}

Затем создайте новый столбец в вашей сетке и заполните его следующими данными:

<?php $this->widget('zii.widgets.grid.CGridView', array(
  'id'=>'business-grid',
  'dataProvider'=>$model->yourDataProviderFunction(),
  'columns'=>
    'business_id',
    array(
      'header'=>'Business Contacts', // give new column a header
      'type'=>'HTML', // set it to manual HTML
      'value'=>'$data->contactsToString()' // here is where you call the new function
    ),
    // other columns
)); ?>

EDIT2: еще один способ сделать это , если вы просто хотите распечатать ОДНО из отношения HAS_MANY, - это установить новое (дополнительное) отношение HAS_ONE для той же таблицы:

public function relations()
{
  return array(
    'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname') // original
    'firstBusinesscontact' => array(self::HAS_ONE, 'BusinessContact', 'business_id'), // the new relation
  );
}

Затем в вашем CGridView вы можете просто настроить столбец так:

'columns'=>array(
  'firstBusinesscontact.contact_firstname',
),
0 голосов
/ 13 февраля 2013

Получение только первого контакта может быть достигнуто так же:

$this->widget('zii.widgets.grid.CGridView', array(
  'id'=>'business-grid',
  'dataProvider'=>$model->yourDataProviderFunction(),
  'columns'=>
    'business_id',
     //....
     array(
       'name' => 'contacts.contact_firstname', 
       'value' => '$data->contacts[0]->contact_firstname',  // <------------------------
       'type' => 'raw' 
     );
     //....
),
...