Как изменить последовательность «соединений» в CakePHP? - PullRequest
3 голосов
/ 12 августа 2010

У меня проблема с последовательностью соединений.Подобная проблема была в другом вопросе Управление порядком соединений в CakePHP .Ответ заключался в использовании контейнерного поведения.В моем случае это неприемлемо, потому что у меня есть более глубокие ассоциации, и их можно генерировать слишком много запросов.Containable не генерирует объединения для трехуровневых ассоциаций.Он генерирует дополнительные запросы для каждой записи из таблицы второго уровня.

Мой запрос:

$this->LevelOne->find('all', array(
    'joins' => array(array(
         'table' => 'level_three',
         'alias' => 'LevelThree',
         'type' => 'LEFT',
         'conditions' => array(
              'LevelThree.id = LevelTwo.level_three_field_id'
          )
     ))
));

Проблема здесь в том, что торт генерирует несколько объединений, но объединение таблицы LevelThree выполняется перед объединениями таблиц LevelTwo, и это вызывает ошибку SQLMsgstr "Неизвестный столбец 'LevelTwo.level_three_field_id' в 'предложении'".Если объединение LevelThree будет в конце запроса после всех присоединений LevelTwo, запрос будет нормальным.

Итак, вопрос в том, как изменить последовательность соединений?

Ответы [ 5 ]

5 голосов
/ 14 августа 2010

Наконец-то я понял, как это сделать:

$this->LevelOne->unbindModel(array('belongsTo' => array('LevelTwo')));
$this->LevelOne->find('all', array(
    'joins' => array(
          array(
             'table' => 'level_two',
             'alias' => 'LevelTwo',
             'type' => 'LEFT',
             'conditions' => array(
                  'LevelTwo.id = LevelOne.level_two_field_id'
              )
          ),
          array(
             'table' => 'level_three',
             'alias' => 'LevelThree',
             'type' => 'LEFT',
             'conditions' => array(
                  'LevelThree.id = LevelTwo.level_three_field_id'
              )
          )
     )
));
0 голосов
/ 01 октября 2014
public function selectdata(){
   $option= $this->Group->find('all', 
                    array(
                        'joins' =>
                            array(
                                array(
                                    'table'=> 'user_groups',
                                    'alias'=>'g',
                                    'type'=> 'INNER',
                                    'conditions'=> array('g.group_id =Group.id ')
                                 ),
                                array(
                                    'table'=> 'users',
                                    'alias'=>'u',
                                    'type'=> 'INNER',
                                    'conditions'=> array('u.id = g.user_id')
                                ),
                     ),'fields'=>array('Group.name,Group.created,Group.modified,Group.status,Group.created_by,u.first_name,u.last_name'),
                       'conditions'=>array('g.group_id=Group.created_by or g.user_id=u.id')
//                        ."'".$created_by."'"
                        )
               ); 
             var_dump($option);//die(); 
               if(isset($this->params['requested']))
               {
                       return $option;
               }
               $this->set('groups', $option);

    }
0 голосов
/ 05 апреля 2013
if (!in_array($join, $queryData['joins'])) {
    //$queryData['joins'][] = $join;
      array_unshift($queryData['joins'],$join);
}

Модификатор Vous Pouvez le fichier DboSource.php du coeur (ligne 1510).

0 голосов
/ 23 января 2013

Для тех, у кого есть подобные проблемы, но в отношениях а-ля $ принадлежит, чтобы иметь правильный порядок, вы должны установить его правильно.

Например, когда у вас есть такой код:

var $belongsTo = array(
    'Vacancy',
    'Applicant' => array(
        'className' => 'Person',
    ),
    'Recruiter' => array(
        'className' => 'Person',
    ),
    'Company' => array(
        'conditions' => array('Company.id = Vacancy.company_id'),
    ),
);

Но в результате, всегда получая результаты, когда Vacancy всегда присоединяется последним, вам следует сделать простую вещь: добавить модель "Vacancy" не как значение массива, а как значение ключа =>, как и другие:

var $belongsTo = array(
    'Vacancy' => array(), // Just add empty array here -- all magic is here :)
    'Applicant' => array(
        'className' => 'Person',
    ),
    'Recruiter' => array(
        'className' => 'Person',
    ),
    'Company' => array(
        'conditions' => array('Company.id = Vacancy.company_id'),
    ),
);

Теперь все будет в прямом порядке: вакансии, соискатель, рекрутер и только потом компания.

0 голосов
/ 12 августа 2010

Задумывались ли вы о создании модели HABTM и вставке собственного 'finderQuery' для переопределения запроса модели? http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm

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

function customJoin(){
    return $this->query('CUSTOM QUERY HERE');
}

Затем вызовите его с контроллера:

$this->ModelName->customJoin();

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

...