find() на основе условий в нескольких отношениях HABTM

Я работаю с CakePHP 2.1
Допустим, у меня есть следующие модели и отношения:
Posts принадлежит Edition
Posts HABTM Editors
Posts HABTM Tags

Я рассуждаю из PostsController и я хотел бы найти все Posts принадлежность к определенному Editionи что Editor.id=55 связано и Tag.id=33 относится.

Я нашел много примеров, где найти Posts основанный на условии, касающемся отношения HABTM, выполняется путем "обращения" направления и причины поиска из Editor,

$this->Editor->find('all',
    array(
        'conditions'=>array('Editor.id'=>55),
        'contain'=>array('Post')
    )
);

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

Также используя contain не работает так как отрубает только ветку (editors) но не помогает отфильтровать его родитель (posts).

Как мне это решить?
Может быть, мне нужно прибегнуть к специальным соединениям? И если так, может кто-нибудь объяснить мне, какой подход выбрать?

Редактировать: некоторый псевдокод, чтобы проиллюстрировать, чего я хочу достичь:

$this->Post->find('all',
    array('conditions'=>array(
            'Edition.id'=>4,
             // start pseudo code
            'Post.Editor' => 'has at least one related editor with id=55',
            'Post.Tag' => 'has at least one related tag with id=33',
        )
    )
);

С уважением, Барт

Изменить решение: Следуя @RichardAtHome, я создал решение ниже. Не (пока) не применялось несколько условий соединения, но в этом не было необходимости:

// Paginate over Cards that belong to current Subscription (belongsTo) AND the User is related to as an Editor (HABTM)
$this->paginate = array(
    'fields' => array('id','title','workingtitle','attachment_count','subscription_id'),
    'joins' => array(
        // create Editor-join
        array(
            'table' => 'cards_users',
            'alias' => 'Editor',
            'type' => 'left',
            'conditions' => array(
                'Editor.card_id = Card.id'
            )
        ), 
        array( 
            'table' => 'users', 
            'alias' => 'User', 
            'type' => 'left',
            'conditions'=> array( 
                'User.id = Editor.user_id'
            ) 
        )
    ),
    'conditions' => array(
        'OR' => array(
            // is Card in current subscription? (straightforward condition)
            array('Card.subscription_id',$subscription_id),
            // is current User assigned as Editor? (condition works with join above)
            array('User.id' => $user['id'])
        )
    ),
    'limit' => 10
);

2 ответа

Решение

Для этого типа запроса я обычно нахожу, что самому проще создавать объединения, так как торт не будет объединяться, вместо этого он выполнит несколько запросов (выберите подходящие строки из таблицы a, а затем извлеките соответствующие строки из таблицы b).

Ваш запрос должен выглядеть примерно так:

$this->Post->find('all',
    array(
        'conditions'=>array('Post.edition_id'=>4),
        'joins'=>array(
            array(
                'type'=>'inner',
                'table'=>'posts_editors',
                'alias'=>'PostsEditor',
                'conditions'=>array(
                    'PostsEditor.post_id = Post.id',
                    'PostsEditor.editor_id'=>55 // your criteia for editor id=55
                )
            ),
            array(
                'type'=>'inner',
                'table'='posts_tags',
                'alias'=>'PostsTag',
                'conditions'=>array(
                    'PostsTag.post_id = Post.id',
                    'PostsTag.tag_id'=>33 // your criteria for tag id = 33
                )

            )
        )
    )
);

Проверьте выводимый SQL, чтобы увидеть, что на самом деле делает этот запрос.

Пытаться:

$this->Post->find('all',
        array('conditions'=>array(
                'Edition.id'=>4,
                'Editor.id' => '55',
                'Tag.id' => '33',
            )
        )
    );
Другие вопросы по тегам