Нежелательные параметры формы добавляются к ссылкам разбивки на страницы

#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 %>