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?
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.
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" %>
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
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. :)