Questo è un problema che sto incontrando regolarmente. Vorrei spiegarlo con un esempio semplificato:Rails: filtro multiselect con un'opzione vuota
Dire che voglio mostrare una pagina di ricerca in cui i risultati possono essere filtrati selezionando una o più categorie di prodotti. Dal punto di vista, questo appare come:
<%= select_tag("product_categories", options_from_collection_for_select(@product_categories, 'id', 'name'), multiple:true, include_blank:"(all categories)" %>
Ora, nel controller, ho qualcosa di simile:
@filtered_products = Product.all
...
if params[:product_categories].present?
@filtered_products = @filtered_products.where(category_id: params[:product_categories].map(&:to_i))
end
...
#etc
Tuttavia, come è impossibile deselezionare una selezione multipla quando ha cliccato, c'è un'opzione vuota. Ma, quando questa opzione è impostata, params[:product_categories]
contiene [""]
. Ciò si traduce nell'istruzione if da valutare e come "" .to_i == 0, otteniamo solo prodotti con categoria 0 (che di solito non è nessuno, poiché ActiveRecord avvia ID da 1 nel database). Questo non è il risultato desiderato, dato che in effetti vogliamo i prodotti tutti quando è selezionata l'opzione vuoto.
La gestione di questo caso è resa ancora più difficile dal momento che è possibile selezionare accidentalmente sia l'opzione vuota che una o più opzioni. Quindi questo caso deve essere gestito anche.
ho cambiato il se-dichiarazione per
if params[:product_categories].present? && params[:product_categories].any? && (params[:product_categories].length > 1 || params[:product_categories].first != "")
...
end
Funziona, ma questo codice è molto brutto. Mi chiedo se ci sia un modo più bello, più SECCO, simile a Rails per farlo.