Разбиение на страницы рандомизированного списка записей в блоге с помощью will_paginate
-
03-07-2019 - |
Вопрос
Я хочу предоставить пользователям возможность просматривать записи в моем блоге в случайном порядке.
Я не могу реализовать это таким образом:
@posts = Post.paginate :page => params[:page], :order => 'RANDOM()'
с тех пор, как :order
параметр вызывается при каждом запросе, и поэтому я рискую повторить записи в блоге.
Каков наилучший способ сделать это?
Решение
RAND принимает начальное значение в MySQL:
RAND(N)
Из самого Документы MySQL:
РАНД (), РАНД (N)
Возвращает случайное значение с плавающей запятой v в диапазоне 0 <= v < 1.0.Если указан постоянный целочисленный аргумент N , он используется в качестве начального значения, которое создает повторяющуюся последовательность значений столбца.В следующем примере обратите внимание, что последовательности значений, генерируемые RAND(3), одинаковы в обоих местах, где это происходит.
Другие базы данных должны обладать аналогичной функциональностью.
Если вы используете ТО ЖЕ САМОЕ каждый раз, когда вы вызываете RAND, порядок будет согласован для всех запросов, и вы сможете соответствующим образом разбивать их на страницы.
Затем вы можете сохранить начальное значение в сеансе пользователя, чтобы каждый пользователь видел набор результатов, уникальных для него.
Другие советы
Чтобы каждая страница (сгенерированная по новому запросу) потенциально не содержала повторяющуюся публикацию, вам нужно будет где-то сохранить порядок записей для извлечения по нескольким запросам.
Если вы хотите, чтобы у каждого пользователя был уникальный случайный порядок, сохраните этот порядок в сеансовом массиве идентификаторов.
Если вы не возражаете, чтобы все пользователи имели одинаковый случайный порядок, тогда создайте столбец позиции в таблице posts.
Вы могли бы:order => RANDOM() в вашем исходном запросе, который заполняет @posts, а затем при разбивке на страницы не указывать порядок.
Создать именованная область действия в вашей модели Post, которая инкапсулирует случайное поведение:
class Post < ActiveRecord::Base
named_scope :random, :order => 'RANDOM()'
.
.
.
end
Ваш PostsController
затем код становится:
@posts = Post.random.paginate :page => params[:page]