#ruby #ruby-on-rails-3 #pagination #kaminari
#ruby #ruby-on-rails-3 #разбивка на страницы #kaminari
Вопрос:
У меня есть страница, которая используется для поиска по спискам путем отправки данных с использованием предоставленных форм. Параметры формы передаются через ajax (post-запрос), в таблице поиска создается новая запись, а затем списки отображаются (динамически, на той же странице, с которой отправлена форма) с помощью show
действия для этой записи.
В результатах есть ссылки на разбивку на страницы, предоставленные kaminari, вот так:
<%= paginate matches,
:params => {:controller => 'searches',
# I have to specify the id because my searches are stored in the database
:action => 'show', :id => search.id},
:remote => true %>
Обратите внимание, что ссылки на разбивку на страницы динамически добавляются на страницу. Итак, когда я выполняю новый поиск и получаю новые списки, сервер повторно отображает ссылки на разбивку на страницы.
Вот мое действие show в контроллере searches
def show
@search = Search.includes(:rate).find(params[:id])
@matches = @search.matches.order(sort_column " " sort_direction).page(params[:page])
respond_to do |format|
format.html
format.xml { render :xml => @matches }
format.js
end
end
По какой-то причине, которую я не могу понять, все параметры, которые я использую в формах поиска (а их много), привязываются к URL-адресам разбивки на страницы kaminari, предоставляя мне hrefs, подобные этому:
<a href="/searches/145?massive parameter list omitted" data-remote="true" rel="next">2</a>
Список пропущенных параметров настолько длинный, что он слишком велик, чтобы быть допустимым запросом GET, и я получаю 414
код ошибки.
Как вы можете видеть из приведенного выше действия searches -> show, для ссылок на разбивку на страницы нет необходимости добавлять всю эту информацию. Все, что им нужно, это маршрут, идентификатор и номер страницы.
Как мне предотвратить это?
Кстати, я попытался настроить :method => :post
в настройках kaminari. Похоже, это не помогает. Я использую kaminari v 0.12.4 (последнюю версию) и Rails 3.1.rc4.
Комментарии:
1. Не могли бы вы, пожалуйста, предоставить код, в котором вы генерируете ссылку для поиска? Это просто search_path? Используете ли вы какой-либо gem для поиска?
2. Извините, боюсь, я не понимаю. Что вы подразумеваете под ссылкой для поиска? Поиск выполняется с помощью формы, которая отправляется на
searches_create_path
запрос via POST.3. Вы решили эту проблему? Я испытываю очень похожее? Если да, пожалуйста, предоставьте какую-нибудь подсказку. С уважением
4. Нет, я так и не добрался до сути. Я отошел от этого проекта.
Ответ №1:
Если у кого-то все еще есть проблемы со ссылками разбивки на страницы, здесь есть исправление: Kaminari: исключить базовые параметры формы из ссылок разбивки на страницы
Хотя у меня это не работает, как было описано в описании коммита, в ссылке все еще есть нежелательные параметры (:authenticity_token, :commit, :utf8, :_method), но вы можете исключить их, установив для них значение nil
Например:
paginate @books, params: {authenticity_token: nil, commit: nil, utf8: nil, action: nil}
Результат:
<a href="/books?page=2">2</a>
или
Контроллер:
def index
# here search staff, messing our params hash
@books = Books.all
@pagination_params = normalize_pagination_params
end
private
def normalize_pagination_params
params.inject({}) do |params_hash, p|
unless p[0]=="controller"
params_hash[p[0]] = nil
end
params_hash
end
end
Вид:
paginate @books, params: @pagination_params
Ответ №2:
Общая идея
Вы можете исправить это, отредактировав части разбивки на страницы, чтобы вручную удалить параметры из URL, а затем добавить параметр страницы обратно. Я знаю, что это взлом, но, похоже, это самый быстрый способ исправить эту проблему, если разбивка на страницы нарушена (как это было у меня).
Я расширяю это из решения, опубликованного в отчете об ошибке GitHub по этой проблеме.
Вам необходимо отредактировать каждую из 5 частей ссылки на разбивку на страницы: _page.html.erb
(по номеру), _first_page.html.erb
и _last_page.html.erb
, _prev_page.html.erb
и _next_page.html.erb
.
Вы можете найти нужный номер страницы из локальных переменных, доступных в частичных разделах: current_page
, page
, num_pages
.
Конкретные инструкции
Если вы еще этого не сделали, сгенерируйте части разбивки на страницы в своем приложении, выполнив rails g kaminari:views default
Затем отредактируйте части следующим образом:
#_page.html.erb
<%
unless page.current?
url = url.split('?')[0] '?page=' page.to_s
end
%>
<span class="page<%= ' current' if page.current? %>">
<%= link_to_unless page.current?, page, url, opts = {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %>
</span>
# _first_page.html.erb
<span class="first">
<% url = url.split('?')[0] '?page=1' %>
<%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote %>
</span>
# _prev_page.html.erb
<span class="prev">
<% url = url.split('?')[0] '?page=' (current_page.to_i - 1).to_s %>
<%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote %>
</span>
# _next_page.html.erb
<span class="next">
<% url = url.split('?')[0] '?page=' (current_page.to_i 1).to_s %>
<%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote %>
</span>
# _last_page.html.erb
<span class="last">
<% url = url.split('?')[0] '?page=' num_pages.to_s %>
<%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} %>
</span>
Комментарии:
1. Кто-нибудь знает, как исправить выделение?
2. Это для вас. Жаль, что нам нужно вот так это взломать, но мое приложение работает с вашим кодом. (Не уверен, в чем проблема выделения Брендана; у меня все работает нормально.)
3. Чтобы добавить к утилите это: мне также нужно сохранить параметры, но поместить их в данные post. Вы можете взять данные из правой части раздела и добавить их в
:data => {:params => data}
элемент, а rails ujs с радостью сериализует их для вас при вызове post!4. kaminari: num_pages переименован в total_pages
5. Я попробовал @DGM, что вы предложили, чтобы сохранить параметры, но мои параметры теряются. Вот строка из моей
_last_page.html.erb
с<% data = Rack::Utils.parse_query URI(url).query %>
помощью, чтобы получить мои параметры сохранения, и вот моя ссылка на эту страницу:<%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote, :method => method, :data => { params: data } %>
. Кто-нибудь может сказать мне, что я делаю не так?
Ответ №3:
Вы могли бы попробовать очистить параметры, сохранив только то, что вам нужно, и удалив все остальное перед отображением результатов поиска.
Чтобы использовать post, я думаю, вы пропустили второй шаг, где вам нужно переопределить части ссылки kaminari:https://github.com/amatsuda/kaminari/wiki/Kaminari-recipes
Ответ №4:
Старое сообщение. Лучшее решение.
Если вы используете kaminari для разбивки на страницы вложенных ресурсов с обновлениями ajax, вы обнаружите, что Kaminari пытается создать URL-адрес на основе текущего пути, независимо от заданных вами параметров, что приводит к ошибке маршрутизации.
Самое чистое решение — использовать маршрут с подстановочными знаками.
Если ваши комментарии к записи разбиты на страницы и имеют контроллер комментариев с действием создать и показать, то:
В ваших маршрутах:
match '*path/comments(/:page)' => 'comments#show'
И виджет разбивки на страницы:
<%= paginate @comments, params: { controller: :comments }, remote: true %>