Обратная нумерация страниц с каминари

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

Например, если нормальная разбивка на страницы для {a,b,c,d,e,f,g,h,i} с 3 на страницу:

{a,b,c}, {d,e,f}, {g,h,i}

Тогда обратная нумерация страниц будет:

{g,h,i}, {d,e,f}, {a,b,c}

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

Возможно ли это с kaminari?


person Nick Ginanto    schedule 06.12.2012    source источник
comment
Почему вы просто не разбиваете перевернутый набор данных на страницы? YourModel.order("created_at ASC").page?   -  person thomasfedb    schedule 18.03.2013


Ответы (4)


На Github есть хороший пример репо под названием reverse_kaminari на github. Он предлагает реализацию в соответствии с этими строками (Источник).

class CitiesController < ApplicationController

  def index
    @cities = prepare_cities City.order('created_at DESC')
  end

  private

  def prepare_cities(scope)
    @per_page = City.default_per_page
    total_count = scope.count
    rest_count = total_count > @per_page ? (total_count % @per_page) : 0
    @num_pages = total_count > @per_page ? (total_count / @per_page) : 1

    if params[:page]
      offset = params[:page].sub(/-.*/, '').to_i
      current_page = @num_pages - (offset - 1) / @per_page
      scope.page(current_page).per(@per_page).padding(rest_count)
    else
      scope.page(1).per(@per_page + rest_count)
    end
  end

end

Все кредиты принадлежат Эндрю Джоге. Он также разместил приложение как рабочую демонстрацию.

person Thomas Klemm    schedule 18.03.2013

Kaminary.paginate_array не производит запрос со смещением и ограничением. По причинам оптимизации вы не должны использовать это.

Вместо этого вы можете сделать это:

@messages = query_for_message.order('created_at DESC').page(params[:page]).per(3)

Где query_for_message обозначает любой запрос, который вы используете для получения записей для разбивки на страницы. Например, это могут быть все сообщения определенного разговора.

Теперь в файле просмотра вам просто нужно отобразить @messages в обратном порядке. Например:

<%= render :collection => @messages.reverse, :partial => 'message' %>
<%= paginate @messages %>
person Musaffa    schedule 06.04.2014

Один из способов решить эту проблему: Обратное разбиение на страницы с помощью каминари? Это действительно так. выглядит не очень чисто и не оптимально, но работает :)

person Wojtek B.    schedule 17.03.2013

Да, но метод, который я придумал, не совсем хорош. Фактически, вы должны установить свой собственный порядок:

Message.page(1).per(3).order("created_at DESC").reverse!

Проблема с этим подходом двоякая:

Сначала наоборот! call преобразует область видимости в массив и выполняет запрос, ослабляя некоторые из замечательных аспектов kaminari с использованием областей AR.

Во-вторых, как и при любой обратной разбивке на страницы, ваше смещение будет перемещаться, что означает, что между двумя повторными вызовами вы можете отправить ровно 3 новых сообщения, и вы получите те же самые данные обратно. Эта проблема присуща обратной нумерации страниц.

Альтернативный подход - запросить номер «последней» страницы и увеличить номер страницы до 1.

person Daniel Evans    schedule 28.12.2012
comment
Что-то вроде: pages = Message.count % 3; Message.page(pages - i).per(3).order("created_at DESC")? - person trompa; 09.01.2013
comment
За исключением того, что order("created_at DESC") должно быть order("created_at ASC"), если вы собираетесь придерживаться такого подхода. - person Daniel Evans; 09.01.2013