2016-03-22 2 views
4

Использование Sonata Admin Bundle, который является отличным дополнением для Symfony, я столкнулся с проблемой, описанной ниже.Просмотр списка сортировки в Sonata Admin по полям связанных объектов

Предположим, у нас есть 3 объекта: город, штат и страна. Все они имеют свойства id и name. У города есть много-к-одному отношение к государству, и государство имеет много-к-одному отношение к Стране. Все они должны использовать методы, отображающие значение имени свойства.

Мы можем создать представление списка для объекта City в Sonata администратора, как это:

защищенные функции configureListFields (ListMapper $ listMapper) { $ listMapper -> addIdentifier ('ID') -> Добавить ('name') -> add ('state') -> add ('state.country') ; }

Для иллюстрации вид может выглядеть следующим образом:

|-----||--------------------||--------------------||--------------------| 
| Id ^|| Name^   || State    || State Country  | 
|-----||--------------------||--------------------||--------------------|  
| 1 || New York   || New York   || USA    | 
| 2 || Acapulco   || Guerrero   || Mexico    | 
| 3 || Calgary   || Alberta   || Canada    | 
| 4 || Tijuana   || Baja California || Mexico    | 
| 5 || Vancouver   || British Columbia || Canada    | 
| 6 || Los Angeles  || California   || USA    | 
|-----||--------------------||--------------------||--------------------| 

По-умолчанию список сортируется по столбцам Id и Имя, знак^должен изобразить это. Я хотел бы иметь возможность сортировать список по связанным полям объекта и иметь ссылку, указывающую на действие show для связанного объекта.

Вот как я достиг сортировкой по государства:

//... 
->add('state', null, array(
    'route' => array('name' => 'show'), 
    'sortable' => true, 
    'sort_field_mapping' => array('fieldName' => 'name'), // property name of entity State 
    'sort_parent_association_mappings' => array(array('fieldName' => 'state')) // property state of entity City 
)) 
//... 

Теперь представление списка является сортировкой по свойству имя сущности государственного и все поля в государстве колонке указывают на шоу страницы для текущего состояния:

|-----||--------------------||--------------------||--------------------| 
| Id ^|| Name^   || State^   || State Country  | 
|-----||--------------------||--------------------||--------------------|  
| 3 || Calgary   || Alberta   || Canada    | 
| 4 || Tijuana   || Baja California || Mexico    | 
| 5 || Vancouver   || British Columbia || Canada    | 
| 6 || Los Angeles  || California   || USA    | 
| 2 || Acapulco   || Guerrero   || Mexico    | 
| 1 || New York   || New York   || USA    | 
|-----||--------------------||--------------------||--------------------| 

Как я сортировать список по Страна (Город-> Государство-> Страна)? Что-то вроде этого:

|-----||--------------------||--------------------||--------------------| 
| Id ^|| Name^   || State^   || State Country  | 
|-----||--------------------||--------------------||--------------------|  
| 3 || Calgary   || Alberta   || Canada    | 
| 5 || Vancouver   || British Columbia || Canada    | 
| 2 || Acapulco   || Guerrero   || Mexico    | 
| 4 || Tijuana   || Baja California || Mexico    | 
| 6 || Los Angeles  || California   || USA    | 
| 1 || New York   || New York   || USA    | 
|-----||--------------------||--------------------||--------------------| 

Когда я пытаюсь что-то вроде выше фрагменте кода:

//... 
->add('state.country', null, array(
    'route' => array('name' => 'show'), 
    'sortable' => true, 
    'sort_field_mapping' => array('fieldName' => 'country.name'), // property name of entity Country 
    'sort_parent_association_mappings' => array(array('fieldName' => 'state.country')) // property country of entity State 
)) 
//... 

то ошибка генерируется исключение. Я пробовал разные комбинации, но все без успеха.

я мог бы сделать:

protected function configureListFields(ListMapper $listMapper) 
{ 
    $listMapper 
     ->addIdentifier('id') 
     ->add('name') 
     ->add('state.name') 
     ->add('state.country.name') 
    ; 
} 

и получить сортировочную проблема решена, но нет ссылки на лицо.

Официальная документация очень хорошая, но отсутствует эта тема. Итак, как отсортировать представление списка по иерархическим объектам?

ответ

8

На следующий день после публикации вопроса я копал исходный код SonataAdminBundle и Symfony и нашел решение. На самом деле это очень просто.Вот он идет:

//... 
->add(
    'state.country', 
    null, 
    array(
     'associated_property' => 'name', // property name of entity Country 
     'sortable' => true, // IMPORTANT! make the column sortable 
     'sort_field_mapping' => array(
      'fieldName' => 'name' // property name of entity Country 
     ), 
     'sort_parent_association_mappings' => array(
      array('fieldName' => 'state') // property state of entity City 
      array('fieldName' => 'country') // property country of entity State 
     ) 
    ) 
) 
//... 

С associated_property мы устанавливаем свойство, которое должно отображаться. Это может быть опущено, если мы определили метод __toString в объекте. В этом случае это означает, что название страны будет отображаться в столбце.

Для опции sort_field_mapping требуется массив с ключом fieldName, содержащий свойство, с помощью которого мы сортируем. Здесь мы сортируем по названию страны. Однако мы могли бы отсортировать популяции, предположив, что у нас есть это свойство в стране сущности, хотя мы отображаем значение для имени.

И sort_parent_association_mappings - самая интересная деталь. Здесь мы определяем свойства, с помощью которых должен быть создан запрос соединения: City имеет состояние свойства, которое является государством-сущностью, в котором сама страна собственности является страной-сущностью.

Надеюсь, мои объяснения понятны и могут помочь другим людям.

+1

HI! Не могли бы вы внести свой вклад в это как статью поваренной книги в документах Sonata? – greg0ire

+0

Это было бы очень приятно! – OskarStark

+0

Большое спасибо за предложение. Для меня будет честью сделать это. – cezar