Как получить случайную строку в CakePHP 3.0?

Я пытаюсь получить случайную строку с помощью CakePHP 3.0 RC-1, я просмотрел документы.

Используя то, что у меня было из CakePHP 2.X, и используя это как отправную точку для получения случайной строки в CakePHP 3.0 RC-1. Однако это, по-видимому, не подходит для мисс Торт:

$result = $this->Game->find('all')
            ->order('rand()')
            ->limit(1);

Результат ничего не дает. В базе данных есть данные, и я могу получить отдельные записи. (То есть $this->Game->get(20) работает как надо).


person Coreus    schedule 05.02.2015    source источник
comment
У меня отлично работает ... как именно вы проверяете результат (просто отладка $result не будет выполнять запрос)? PS, также попробуйте с недавним снимком разработчика.   -  person ndm    schedule 05.02.2015
comment
просто var_dump весь объект $game в представлении или в контроллере, если на то пошло. Это самый последний снимок разработчика.   -  person Coreus    schedule 05.02.2015
comment
Вот и все, что вы делаете, это сбрасывает запрос, а не результат. Сначала вам нужно будет что-то получить, например, с помощью first() (тогда вы можете отказаться от limit()). См. book.cakephp.org/ 3.0/en/orm/query-builder.html#the-query-object   -  person ndm    schedule 05.02.2015
comment
Тогда почему я вижу результат, если я var_dump результирующего набора через ->GET, а не через код, указанный выше?   -  person Coreus    schedule 12.02.2015
comment
Потому что Table::get() вызывает Query::firstOrFail() внутри (который снова вызывает Query::first()). Я бы посоветовал проверить источник (поможет правильная IDE, которая позволяет вам щелкать вызовы методов).   -  person ndm    schedule 12.02.2015


Ответы (1)


Просто используйте «first» для получения первого результата:

$result = $this->Game->find('all')
        ->order('rand()')
        ->first();

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

$result = $this->Game->find('all')
        ->order('rand()')
        ->firstOrFail();
person José Lorenzo Rodríguez    schedule 05.02.2015
comment
Это работает, но насколько это эффективно, если вы не ограничиваете себя? (Найдите все звуки, как будто вы получаете большой набор результатов, а затем получаете первый из них) - person Coreus; 12.02.2015
comment
Использование RAND() всегда ужасно, так как нужно получить все результаты, упорядочить их случайным образом, а затем нарезать результаты. Что касается вашего вопроса, firstOrFail применит к вам LIMIT 1. Однако это не означает, что RAND() будет работать быстрее. - person José Lorenzo Rodríguez; 12.02.2015
comment
Конечно, но опять же вы можете активировать кэширование запросов, ограничивая влияние. - person Coreus; 13.02.2015