Результаты запроса CakePHP на более чем 1 уровне - PullRequest
2 голосов
/ 18 января 2010

Я использую поведение Containable для получения списка комментариев (принадлежит сообщению, которое принадлежит вопросу; вопрос имеет много сообщений, и сообщение имеет много комментариев; все они принадлежат пользователям).

$data = $this->Question->find ( 'first', 
    array ('contain' => 
        array ('User', 
               'Post' => array ('User', /* 'order' => 'User.created DESC'*/ )
        ) 
    ) 
);

Это работает, когда я комментирую раздел в комментариях выше. Я предполагаю, что этого и следовало ожидать, но я хочу, чтобы все найденные сообщения были отсортированы в порядке «созданного» поля «Пользователь», которому они принадлежат. Как мне выполнить эту более глубокую сортировку уровней в CakePHP? Я всегда получаю: «Предупреждение (512): ошибка SQL: 1054: неизвестный столбец« User.created »в« предложении заказа »»

Спасибо за вашу помощь!

Ответы [ 5 ]

3 голосов
/ 19 января 2010

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

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

Если вы хотите вручную принудительно объединить в этих ситуациях, вы можете использовать метод Ad-Hoc, описанный Нейтом по следующей ссылке.

http://bakery.cakephp.org/articles/view/quick-tip-doing-ad-hoc-joins-in-model-find

1 голос
/ 07 июня 2011

Я нашел два способа обойти это. Первый - определить ассоциацию второго уровня непосредственно в модели. Теперь вы будете иметь доступ к этим данным везде. Это должно выглядеть примерно так .....

var $belongsTo = array(
'Foo' => array(
  'className' => 'Foo', //unique name of 1st level join ( Model Name )
  'foreignKey' => 'foo_id', //key to use for join
  'conditions' => '',
  'fields' => '',
  'order' => ''
),
'Bar' => array(
  'className' => 'Bar', //name of 2nd level join ( Model Name )
  'foreignKey' => false,
  'conditions' => array(
    'Bar.id = Foo.bar_id' //id of 2nd lvl table = associated column in 1st level join
  ),
  'fields' => '',
  'order' => ''
)
);

Проблема этого метода в том, что он может сделать общие запросы более сложными, чем они должны быть. Таким образом, вы также можете добавлять запросы второго уровня непосредственно в оператор find или paginate следующим образом: (Примечание: я обнаружил, что по какой-то причине вы не можете использовать ассоциации $ ownTo в соединениях второго уровня, и вам потребуется переопределить их, если уже определены, например, если 'Foo' уже определено в $ ownTo, вам нужно создать дубликат 'Foo1', чтобы заставить ассоциацию работать, как в примере ниже.)

$options['joins'] = array(

array('table' => 'foos',
  'alias' => 'Foo1',
  'type' => 'inner',
  'conditions' => array(
    'CurrentModel.foo_id = Foo1.id'
  )
),
array('table' => 'bars',
  'alias' => 'Bar',
  'type' => 'inner',
  'foreignKey' => false,
  'conditions' => array(
    'Bar.id = Foo1.bar_id'
  )
)
);

$options['conditions'] = array('Bar.column' => "value");
$this->paginate = $options;
$[modelname] = $this->paginate();
$this->set(compact('[modelname]'));

Надеюсь, это достаточно ясно, чтобы понять и помочь кому-то.

0 голосов
/ 18 января 2012

Да, я не мог понять, как сортировать на основе связанной / ассоциированной модели, поэтому в итоге использовал метод Set::sort().Изучите эту статью для хорошего объяснения.

// This finds all FAQ articles sorted by:
// Category.sortorder, then Category.id, then Faq.displaying_order
$faqs = $this->Faq->find('all', array('order' => 'displaying_order'));
$faqs = Set::sort($faqs, '{n}.Category.id', 'ASC');
$faqs = Set::sort($faqs, '{n}.Category.sortorder', 'ASC');

... И да, это, вероятно, должно быть Category->find(), но, к сожалению, оригинальный разработчик не кодировал его таким образоми я не хотел переделывать взгляды.

0 голосов
/ 18 января 2010

Вы можете добавить перед вызовом, чтобы найти () следующее:

 $this->Question->order = 'Question.created DESC';
0 голосов
/ 18 января 2010

Проверьте рекурсивное значение.Если он слишком ограничен, он игнорирует содержащиеся ссылки, IIRC.Я помню, что сталкивался с этим несколько раз.Я бы попытался содержать несколько моделей, но мой параметр recursive был установлен на 0, и ничего не получалось.Для вашего примера, я думаю, что значения 1 (по умолчанию) будет достаточно, но, может быть, вы явно указали его где-то 0?

...