Я пытаюсь реализовать простой поиск и сортировку моего веб-приложения. Я слежу за 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? Что я делаю не так?

35
Saurav Prakash 4 Сен 2017 в 04:01

5 ответов

Лучший ответ

В Rails 5 ActionController::Parameters больше не наследуется от Hash, пытаясь отговорить людей использовать связанные с Hash методы для параметров запроса без явной их фильтрации.

В рамках этого запроса на извлечение, который был перенесен в 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), поэтому обычно это рискованный подход.

70
Max 18 Сен 2019 в 02:16

Я полагаю, что если вы пропустите колонку, чтобы разрешить ее, вы снова заработаете!

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
4
Mike Langston 6 Июн 2018 в 13:52

Вы можете попробовать использовать request.parameters.merge, ниже приведен пример кода выше

<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %>  
9
widjajayd 4 Сен 2017 в 01:24

Вы можете использовать этот хак:

params.to_enum.to_h

Я думаю, что разработчики rails ограничат это, когда узнают, что это способ использовать недопустимые параметры. :)

22
Ghazi 15 Фев 2019 в 10:29

Вы также можете перезаписать, выполнив params.permit! Это может создать угрозу безопасности, поэтому будьте осторожны при использовании этого.

1
FutoRicky 30 Мар 2020 в 19:57