2010-06-03 2 views
1

Мне нужно найти все записи для определенного ресурса и отобразить их в произвольном порядке, но с последовательной разбивкой на страницы (вы не увидите одну и ту же запись дважды, если начнете пейджинг). Порядок отображения должен быть рандомизирован каждый раз, когда пользователь посещает страницу. Я использую will_paginate. Любой совет?Rails Случайная активная запись с разбиением на страницы

ответ

4

Храните случайное число в cookie сеанса пользователя, а затем используйте его как семя для случайной функции базы данных. Это будет то же самое, пока пользователь не закроет свой браузер, и, таким образом, все они будут видеть случайные, последовательные записи:

Получить большое, случайное число:

cookies[:seed] = SecureRandom.random_number.to_s[2..20].to_i 

Используйте это семя, например, с MySQL:

SomeModel.all.order("RAND ?", cookies[:seed]) 
+0

Обновление: я только что понял одно: вы, вероятно, должны сделать случайное семя частью своих URL-адресов, так что, когда пользователь сохраняет закладку или сохраняет URL-адрес, он не будет разбивать разбиение на страницы. Затем вы можете сделать семя || = params [: seed] || session_seed – Houen

1

Если вы используете базу данных, такие как MySQL, которая имеет функцию Randomize, такую ​​как RAND(), вы можете просто добавить, что к вашему постраничному запросу следующим образом:

Resource.paginate(... :order => "RAND()" ...) 

Проверьте некоторые из комментариев здесь относительно : https://rails.lighthouseapp.com/projects/8994/tickets/1274-patch-add-support-for-order-random-in-queries

+0

Это не будет работать. При смене страниц (например, от 1 до 2) запрос выполняется во второй раз, и появляется возможность дублирования записи (запись, которая была на стр. 1 также показана на стр. 2). –

+0

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

+0

Да, это не похоже на очень хорошее решение. Я просто немного удивлен, что лучше не существует. Я видел, как это реализовано ранее в приложениях Ruby on Rails, таких как http://sortfolio.com/. –

2

Это не стандартно, насколько мне известно. Я могу видеть это для этого, например, для онлайн-тестов.

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

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

Надеюсь, это поможет.

1

Не уверен, что вам все еще нужна помощь. Одно из решений, которое я делал в прошлом, - это выполнить запрос с RAND, но без разбивки на страницы сначала. Затем сохраните эти идентификаторы записей и используйте этот сохраненный список для поиска и разбивки на страницы. Исходный запрос RAND можно было установить только для того, чтобы страница была 1 или ноль. Просто мысль.

+0

Спасибо за идею.Я не смотрел на это в течение долгого времени и не могу вспомнить, где он использовался больше! Хотя я благодарен за ответ. –

0

Я закончил вверх с этим решением, который работал для меня на Postgres:

session[:seed] ||= rand() # should be between [-1..1] 
seed = session[:seed] 
Product.select("setseed(#{seed})").first 
Product.order('random()').limit(10).offset(params[:offset]) 
Смежные вопросы