This is a problem that I encounter regularly. Let me explain this with a simplified example:
Say I want to show a search page where you can filter the results by selecting one or more product categories. In the view, it looks like this:
<%= select_tag("product_categories", options_from_collection_for_select(@product_categories, 'id', 'name'), multiple:true, include_blank:"(all categories)" %>
Now, in the controller, I have something like:
@filtered_products = Product.all ... if params[:product_categories].present? @filtered_products = @filtered_products.where(category_id: params[:product_categories].map(&:to_i)) end ...
However, since it is not possible to deselect multi select when pressed, an empty parameter exists. But, when this parameter is set, params[:product_categories] contains [""] . This leads to the calculation of the if-statement, and as "" .to_i == 0, we get only products with category 0 (usually not, since ActiveRecord runs identifiers from 1 in the database). This is not the desired result, since in fact we want everyone to be when choosing an empty parameter.
Handling this case is even more difficult, because you can randomly select either an empty parameter or one or more other parameters. Therefore, this case also needs to be handled.
I changed the if-statement to
if params[:product_categories].present? && params[:product_categories].any? && (params[:product_categories].length > 1 || params[:product_categories].first != "") ... end
This works, but this code is very ugly. I am wondering if there is a nicer, more severe, Rails-like way to do this.