Как воспроизвести глубокий поиск Cake с ручным соединением

У меня есть следующий код:

$current_user = $this->User->find('first', array(
    'recursive' => -1,
    'conditions' => array('User.id' => $user_id),
    'fields' => array(
        //User
        'User.id',
        //Profile
        'Profile.user_id',
        'Profile.id',
        'Profile.first_name',
        'Profile.last_name',
        'Profile.media_asset_id',
        //Profile Picture
        'MediaAsset.id'
    ),
    'joins' => array(
        array(
            'table' => 'profiles',
            'alias' => 'Profile',
            'type' => 'left',
            'conditions' => array(
                'Profile.user_id = User.id'
            )
        ),
        array(
            'table' => 'media_assets',
            'alias' => 'MediaAsset',
            'type' => 'left',
            'conditions' => array(
                'MediaAsset.id = Profile.media_asset_id'
            )
        )
    )
));

И объединения работают отлично, то есть возвращают User, Profile и MediaAsset. Однако, если бы я позволил Cake сделать это для меня, это привело бы к этой структуре: (пример 1)

User
Profile
---- MediaAsset

Однако руководство находит это следующим образом: (пример 2)

User
Profile
MediaAsset

В любом случае, без дополнительных запросов я могу получить его, как Cake?

Спасибо, Джош.

** Редактировать Чтобы уточнить, чего я пытаюсь достичь. В моей базе данных будет много таблиц, и многие из этих таблиц ссылаются на пользователя. Однако я не хочу извлекать их все, так как это пустая трата ресурсов. Из-за этого я указываю ручное объединение для запросов, которые я запускаю при каждом запросе, например для текущего пользователя.

Проблема в том, что мне нужно получить MediaAsset в профиле, и это нормально (см. пример 2). Но красивое форматирование Cake имеет гораздо больше смысла.

**В скроулер Эта находка приводит к возврату всего (Пользователь, Профиль, Гараж, Предпочтение, любая модель, имеющая user_id)

if (!$username || !$user = $this->find('first', array(
        'conditions' => array('User.username' => $username),
        'contain' => array(
            'Profile'
        )
    ))) {
    throw new NotFoundException('User not found');
}

person jshthornton    schedule 16.01.2014    source источник
comment
Можете ли вы объяснить немного больше?   -  person Anubhav    schedule 16.01.2014
comment
@Anubhav, написал правку. Это помогает?   -  person jshthornton    schedule 16.01.2014
comment
Вам нужен вложенный массив для MediaAsset? Если это так, и вы не хотите использовать отношение модели Cake, я думаю, вам, возможно, придется написать его вручную... например. foreach($current_user as $key => $user){ $current_user[$key]['MediaAsset'] = $this->MediaAsset->find('all', array('conditions' => array('MediaAsset.id' => $user['Profile']['media_asset_id']))); } - однако, поскольку Cake создан для того, чтобы делать такие вещи для вас, не лучше ли было бы связать его через ассоциации моделей?   -  person scrowler    schedule 16.01.2014
comment
@scrowler Это все связано. Я пытаюсь понять, что у меня много моделей и много таблиц. Во многих случаях мне не нужно, чтобы Cake ссылался туда и обратно повсюду и предоставлял множество запросов, которые избыточны для страницы.   -  person jshthornton    schedule 16.01.2014
comment
Вот для чего предназначено сдерживаемое поведение. Установите в своей модели вместимость, а затем просто поместите 'contain' => array(Associated, models, you, DO, want, here) в вызов поиска: book.cakephp.org/2.0/en/core-libraries/behaviors/   -  person scrowler    schedule 16.01.2014
comment
@scrowler, я пытался содержать в прошлом, однако, похоже, он игнорирует это и просто загружает все, что может быть связано с ним. Я опубликую пример в основном вопросе   -  person jshthornton    schedule 16.01.2014
comment
Вы добавили сдерживаемое поведение в свою модель?   -  person Ben Hitchcock    schedule 16.01.2014


Ответы (1)


в моем AppModel.php у меня есть:

public $actsAs = array('Containable');

затем в модели, где у меня есть метод поиска:

$rs = $this->find('all', array(
        'recursive' => -1,
        'order' => array('User.created DESC'),
        'contain' => array(
            'Profile' => array(
               'MediaAsset' => array('fields' => array('id','profile_id' .... ),
               'fields' => array('id', 'created', .... )),
        ),
    ));

все работает без проблем, только не забудьте добавить 'recursive' => -1 при использовании contains.

person thanat    schedule 31.01.2014