Jest to problem, z którym się spotykam regularnie. Pozwolę sobie wyjaśnić to na uproszczonym przykładzie:Szyny: filtrowanie wielosegmentowe z pustą opcją
Powiedz, że chcę pokazać stronę wyszukiwania, na której wyniki można filtrować, wybierając jedną lub wiele kategorii produktów. Z punktu widzenia wygląda to tak:
<%= select_tag("product_categories", options_from_collection_for_select(@product_categories, 'id', 'name'), multiple:true, include_blank:"(all categories)" %>
Teraz w sterowniku, mam coś takiego:
@filtered_products = Product.all
...
if params[:product_categories].present?
@filtered_products = @filtered_products.where(category_id: params[:product_categories].map(&:to_i))
end
...
#etc
Jednakże, jak to jest możliwe, aby odznaczyć multiselect kiedy kliknął, jest pusta opcja. Ale po ustawieniu tej opcji params[:product_categories]
zawiera [""]
. Wynikiem tego jest instrukcja if do oceny, a jako "" .to_i == 0, otrzymujemy tylko produkty z kategorią 0 (która zwykle nie występuje, ponieważ ActiveRecord uruchamia identyfikatory od 1 w bazie danych). Nie jest to pożądany wynik, ponieważ w rzeczywistości chcemy uzyskać produkty wszystkie, gdy wybrana jest opcja pusta.
Obsługa tego przypadku jest jeszcze trudniejsza, ponieważ możliwe jest przypadkowe wybranie zarówno pustej opcji, jak i jednej lub wielu innych opcji. Więc ta sprawa również musi być rozpatrzona.
Zmieniłem if-oświadczenie
if params[:product_categories].present? && params[:product_categories].any? && (params[:product_categories].length > 1 || params[:product_categories].first != "")
...
end
To działa, ale ten kod jest bardzo brzydka. Zastanawiam się, czy istnieje lepszy, bardziej suchy, podobny do Railsów sposób, aby to zrobić.