2013-04-22 2 views
0

Я попытался найти ответ на этот вопрос, так как я уверен, что его кое-что было выяснено раньше, но я не мог найти ничего, что обсуждало бы то, как cakephp форматирует данные, возвращаемые с Модели. Обычно я просто вижу, как поступают данные, и обрабатывать их по мере необходимости для каждого контроллера/представления. В этом случае, однако, я хочу повторно использовать свои взгляды, к сожалению, способ, которым cakephp передает мне данные от разных контроллеров, вызывает у меня проблемы.Как я могу изменить способ, которым cakephp передает данные для связанной модели?

У меня есть 2 модели, связаны следующим образом:

class Group extends AppModel { 
public $hasMany = array( 'User'); 
} 

class User extends AppModel { 
public $belongsTo = array(
'Group' ); 
} 

Я хочу, чтобы показать мне View/Groups/view/id детали для отдельных групп, а также список пользователей, которые принадлежат к группе. В идеале я не хочу воссоздавать код для отображения списка пользователей, поскольку он уже существует в View/Users/index

Я обнаружил, что могу использовать $ this-> extend ('/ Users/index'), но я могу 't просто используйте `$ this-> set (' users ', $ group [' User ']), как я хочу, потому что массив построен по-разному.

В UsersController :: индекс() Я бы назвал $users = $this->find('all');, который содержит список пользователей, как это: debug($users);

array(
(int) 0 => array(
    'User' => array(
     'id' => '100', 
     'group_id' => '101', 
    ) 
), 
(int) 1 => array(
    'User' => array(
     'id' => '101', 
     'group_id' => '101', 
    ) 
) 
) 

В GroupsController является использование $ this-> группы-> содержит (массив ('User «)); $ group = $ this-> GroupsController-> Group-> find ('first', 'conditions' => array ('id' => $ id);

Что возвращает список групп, но в этом формат вместо debug($group['User']);

'User' => array(
    (int) 0 => array(
     'id' => '101', 
     'group_id' => '101', 
    ), 
    (int) 1 => array(
     'id' => '100', 
     'group_id' => '101', 

    ) 
) 

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

ответ

0

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

Вместо реализации нормализации для этого, я рекомендовал бы модифицируя найти() вызов:

$group = $this->GroupsController->Group->User->find('list', array(
    'conditions' => array('User.group_id' => $id) 
)); 

Примечание: Использование содержат(), когда вам не нужно это добавляет дополнительные вливается в ваш запрос, который будет влиять на производительность.

Я предпочитаю не нормализовать/переформатировать мои данные CakePHP, потому что это делает его нестандартным. CakePHP всегда возвращает данные предсказуемым образом, это просто вопрос привыкания к нему и использование соответствующих методов для извлечения ваших данных.

Получение прямого данных будет возвращать его в формате:

array(
    (int) 0 => array(
     'MODEL' => array(
      'field1' => 'value1', 
      'field2' => 'value2', 
     ) 
    ), 
    (int) 1 => array(
     'MODEL' => array(
      'field1' => 'value1', 
      'field2' => 'value2', 
     ) 
    ) 
) 

Получение прямых данных и связанных с ними-данных (с помощью Содержать) будет возвращать его в формате:

array(
    (int) 0 => array(
     'MODEL' => array(
      'field1' => 'value1', 
      'field2' => 'value2', 
      'RELATEDMODEL' => array(
       (int) 0 => array(
        'field1' => 'value1' 
        'field2' => 'value2' 
       ), 
       (int) 1 => array(
        'field1' => 'value1' 
        'field2' => 'value2' 
       ) 
      ) 
     ) 
    ), 
    (int) 1 => array(
     'MODEL' => array(
      'field1' => 'value1', 
      'field2' => 'value2', 
      'RELATEDMODEL' => array(
       (int) 0 => array(
        'field1' => 'value1' 
        'field2' => 'value2' 
       ), 
       (int) 1 => array(
        'field1' => 'value1' 
        'field2' => 'value2' 
       ) 
      ) 
     ) 
    ) 
) 

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

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

Есть несколько способов, которыми это можно было бы сделать, но наиболее подходящим способом было бы реализуйте нормализацию данных в обратном вызове afterFind() вашей модели (или AppModel).

Этот обратный вызов попал после каждого найти на соответствующей модели. Реализация его в AppModel :: afterFind() повлияет на каждый поиск в вашем приложении.

Боковое примечание: простой способ нормализовать данные - использовать Set :: extract(), однако, по моему опыту, это может привести к большему количеству накладных расходов, чем самим прохождением данных из-за того, насколько надежна реализация. Может быть, хорошая идея взглянуть и посмотреть, соответствует ли она вашим потребностям. Лично я не использовал бы его сам в afterFind() из-за чрезмерного заголовка, который мог бы добавить, однако я включаю его здесь, так как он может соответствовать вашим потребностям.

1,3 Набор Извлечение документов:

2,0 Набор экстракта документация:

Что касается опасений по эффективности: Выполнение регулярного цикла не добавит много накладных расходов на всех. Однако с учетом сказанного, нормализация, конечно, добавит немного накладных расходов.

+0

спасибо. Я не знал, что сдерживаемое изменилось, как связанные данные были привязаны к основной модели. После того, как я прочитал, как настраиваемое сдерживаемое поведение я начал использовать, как один инструмент подходит всем. Как вы предположили, я решил, что лучшим вариантом для меня было использовать один вызов для '$ group = $ this-> Group-> findByID ($ id)', а другой для '$ users = $ this-> Group-> User- > find ('all') 'с условием на group_id. –

+0

Отлично! Рад был помочь. – jrace

0

Действительно, ручная модификация массива не рекомендуется. Попытка повлиять на то, как модели возвращают связанные данные, также не рекомендуется.

Лучшее, что я могу придумать, следующее.

Если предположить, что индекс пользователей есть что-то вроде:

foreach($users as $user) { 
    debug($user['User']); // made up for brevity 
} 

Добавьте следующую строку в начале foreach блока:

if (!isset($user['User']) { 
    $user = array('User' => $user); 
} 

Это не кажется, что все дорого.

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