CakePHP упорядочивает результаты запроса более чем на 1 уровне

StackOverflow https://stackoverflow.com/questions/2086509

  •  21-09-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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 следующим образом:(Примечание:Я обнаружил, что по какой-то причине вы не можете использовать ассоциации $belongsTo в объединениях второго уровня, и вам нужно будет переопределить их, если они уже определены.например, если 'Foo' уже определено в $belongsTo, вам нужно создать дубликат '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]'));

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

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

Вы можете добавить перед вызовом функции find() следующее:

 $this->Question->order = 'Question.created DESC';

Да, я не смог разобраться, как сортировать на основе связанной модели, поэтому в итоге использовал 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() но, к сожалению, первоначальный разработчик не закодировал это таким образом, и я не хотел переделывать представления.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top