web-dev-qa-db-fra.com

Rails Impossible de convertir les paramètres non autorisés en hachage

J'essaye d'implémenter une recherche simple et un tri pour mon webapp. Je suis le railscast et ce railscast

Mon assistant d'application pour la fonction de tri que j'utilise comme lien est le suivant:

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

Je les utilise dans la vue. Dans le contrôleur, j'utilise la liste blanche comme:

 @listingssearch.where(:vehicletype => 'Car').order(sort_column + " " + sort_direction).paginate(:page => params[:page], :per_page => 30)

Méthodes privées d'assainissement:

 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

J'ai essayé d'utiliser la fusion dans la méthode privée:

(Listing.column_names + params) but its not working 

Pour les méthodes d'assistance Je reçois une erreur lorsque j'essaie de fournir des paramètres de recherche au lien de tri: impossible de convertir les paramètres non autorisés en hachage

Il montre que l'erreur est pour la fusion

link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}

L'autre méthode fonctionne bien:

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

Ma question est: comment conserver les paramètres de recherche dans les méthodes d'aide au tri dans Rails 5? Qu'est ce que je fais mal?

10
Saurav Prakash

Dans Rails 5, ActionController::Parameters n'hérite plus de Hash, dans le but de décourager les personnes d'utiliser des méthodes liées à Hash sur les paramètres de requête sans les filtrer explicitement.

Dans le cadre de this pull request , qui a été rétroporté dans Rails 5.1 et partiellement dans Rails 5.0, une exception est générée si vous essayez d'appeler to_h sur l'objet de paramètres sans appeler permit.

L'appel de merge sur l'objet params d'origine (params.merge(:sort => column, :direction => direction, :page => nil)) renvoie un nouvel objet ActionController::Parameters ayant le même statut permitted (en d'autres termes, permit n'a pas été appelé). La méthode link_to finit alors par appeler to_h sur cet objet, ce qui déclenche l'exception.

Si vous savez quels paramètres doivent être autorisés dans le lien, vous pouvez appeler permit avec ceux répertoriés.

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)

Si vous ne savez pas quels paramètres pourraient être inclus dans le lien, vous pouvez utiliser request.parameters.merge(...) (comme indiqué dans cette réponse ) ou params.to_unsafe_h.merge(...). Ces deux contournent fondamentalement la protection des paramètres forts lors de la création du lien. Par défaut, cela signifie que tous les paramètres figurant dans la demande d'origine apparaissent également dans l'URL du lien. Je suppose que cela n’est pas trop risqué dans cette situation particulière, mais si vous avez du code ailleurs qui nettoie pas correctement les paramètres, cela pourrait aggraver la situation.

29
Max

vous pouvez essayer d'utiliser request.parameters.merge, voici un exemple de votre code

<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %>  
3
widjajayd

Je crois que si vous passez la colonne pour permettre cela devrait vous faire travailler à nouveau!

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
1
Mike Langston

Vous pouvez utiliser ce hack:

params.to_enum.to_h

Je pense que les développeurs de Rails vont le restreindre quand ils sauront que c'est le moyen d'utiliser des paramètres non autorisés. :)

1
Ghazi