Dies ist ein Problem, auf das ich regelmäßig stoße. Lassen Sie mich das anhand eines vereinfachten Beispiels erklären:Rails: Multiselect-Filterung mit einer leeren Option
Angenommen, ich möchte eine Suchseite anzeigen, auf der Ergebnisse durch Auswahl einer oder mehrerer Produktkategorien gefiltert werden können. In der Ansicht, das sieht aus wie:
<%= select_tag("product_categories", options_from_collection_for_select(@product_categories, 'id', 'name'), multiple:true, include_blank:"(all categories)" %>
nun in der Steuerung, ich habe so etwas wie:
@filtered_products = Product.all
...
if params[:product_categories].present?
@filtered_products = @filtered_products.where(category_id: params[:product_categories].map(&:to_i))
end
...
#etc
Da es jedoch unmöglich ist, deaktivieren eine Mehrfachauswahl, wenn darauf geklickt hat, Es gibt eine leere Option. Wenn diese Option jedoch festgelegt ist, enthält params[:product_categories]
[""]
. Dies führt dazu, dass die if-Anweisung ausgewertet wird, und als "" .to_i == 0 erhalten wir nur Produkte mit Kategorie 0 (was normalerweise keine ist, da ActiveRecord IDs von 1 in der Datenbank startet). Dies ist nicht das gewünschte Ergebnis, denn in der Tat wollen wir alle Produkte, wenn die leere Option ausgewählt ist.
Die Handhabung dieses Falles wird noch schwieriger, weil es möglich ist, versehentlich sowohl die leere Option als auch eine oder mehrere andere Optionen auszuwählen. Also muss auch dieser Fall behandelt werden.
ich mich verändert habe die if-Anweisung
if params[:product_categories].present? && params[:product_categories].any? && (params[:product_categories].length > 1 || params[:product_categories].first != "")
...
end
Es funktioniert, aber dieser Code ist sehr hässlich. Ich frage mich, ob es eine schönere, trockenere, Schienen-ähnliche Art gibt, dies zu tun.