Rails Невозможно преобразовать неперечисленные параметры в хэш
Я пытаюсь реализовать простой поиск и сортировку моего веб-приложения. Я слежу за Railscast и этим Railscast.
Помощник моего приложения для сортируемой функции, которую я использую в качестве ссылки:
def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
end
Я использую их в представлении. В контроллере я использую белый список как:
@listingssearch.where(:vehicletype => 'Car').order(sort_column + " " + sort_direction).paginate(:page => params[:page], :per_page => 30)
Частные методы санации:
private
def sort_column
Listing.column_names.include?(params) ? params[:sort] : "rateperhour"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
Я пытался использовать слияние в приватном методе:
(Listing.column_names + params) but its not working
Для вспомогательных методов я получаю сообщение об ошибке при попытке указать параметры поиска для ссылки на сортировку: невозможно преобразовать недопустимые параметры в хэш
Это показывает, что ошибка для слияния
link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
В остальном работает нормально:
<%= bootstrap_form_for listings_path, :method => 'get' do %>
<%= hidden_field_tag :direction, :value => params[:direction] %>
<%= hidden_field_tag :sort,:value => params[:sort] %>
<div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">
<h6 style = "color:#7C064D;"><strong> PICK A DATE <span class="glyphicon glyphicon-calendar"></span></strong>
<%= date_field_tag :startdate, params[:startdate], placeholder: 'DATE' %>
</h6>
</div>
<div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">
<p>
<%= text_field_tag :near, params[:near], placeholder: ' Destination' %>
<%= text_field_tag :radius, params[:radius], placeholder: ' Search Radius' %>
</p>
</div>
<div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">
<p>
<%= text_field_tag :min, params[:min], placeholder: ' Minimum Rate Per Hour' %>
<%= text_field_tag :max, params[:max], placeholder: ' Maximum Rate Per Hour' %>
</p>
</div>
<div class= "col-sm-12 col-lg-12 col-md-12" style = "margin-top: 10px;">
<%= submit_tag "Search", class: "btn btn-info", style: "width: 40%; background-color: #E20049; border: #e20049;" %>
<%= link_to 'View All', root_path, class: "btn btn-info", style: "width: 40%; background-color: #E20049; border: #e20049;" %>
</div>
<!-- <div class= "col-sm-6 col-lg-6 col-md-6" style = "margin-top: 10px;">
</div> -->
<% end %>
Мой вопрос: как сохранить параметры поиска в методах сортировки помощников в rails 5? Что я делаю не так?
Ответы
Ответ 1
В Rails 5 ActionController::Parameters
больше не наследуется от Hash
, пытаясь отговорить людей использовать методы Hash
-related для параметров запроса без явной их фильтрации.
В рамках этого запроса извлечения, который был перенесен в Rails 5.1 и частично в Rails 5.0, возникает исключение, если вы пытаетесь вызвать to_h
для объекта параметров без вызова permit
.
Вызов merge
для исходного объекта params
(params.merge(:sort => column, :direction => direction, :page => nil)
) возвращает новый объект ActionController::Parameters
с тем же статусом permitted
(то есть permit
не был вызван для него). Затем метод link_to
вызывает to_h
для этого объекта, что вызывает исключение.
Если вы знаете, какие параметры должны быть разрешены в ссылке, вы можете вызвать permit
из перечисленных.
params.permit(:param_1, :param_2).merge(:sort => column, :direction => direction, :page => nil)
# OR
params.merge(:sort => column, :direction => direction, :page => nil).permit(:param_1, :param_2, :sort, :direction, :page)
Если вы не знаете, какие параметры могут быть включены в ссылку, тогда можно позвонить request.parameters.merge(...)
(как упомянуто в этом ответе) или params.to_unsafe_h.merge(...)
. Однако, как отмечено в комментариях, это представляет угрозу безопасности, когда результат передается в link_to
, поскольку такой параметр, как host
, будет интерпретироваться как фактический хост для ссылки, а не как параметр запроса. Есть несколько других клавиш, которые также имеют особое значение в link_to
(все, что принято url_for
, плюс :method
), так что обычно это рискованный подход.
Ответ 2
Вы можете использовать этот хак:
params.to_enum.to_h
Я думаю, что разработчики rails ограничат это, когда знают, как использовать недопустимые параметры. :)
Ответ 3
вы можете попробовать использовать request.parameters.merge, ниже пример для вашего кода выше
<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %>
Ответ 4
Я верю, что если вы передадите колонку, чтобы она позволила вам снова работать!
def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, params.permit(column).merge(sort: column, direction: direction, page: nil), { class: css_class }
end