这是我经常遇到的问题.让我通过一个简化的例子解释一下:
假设我想显示一个搜索页面,其中可以通过选择一个或多个产品类别来过滤结果.在视图中,这看起来像:
<%= select_tag("product_categories", options_from_collection_for_select(@product_categories, 'id', 'name'), multiple:true, include_blank:"(all categories)" %>
Run Code Online (Sandbox Code Playgroud)
现在,在控制器中,我有类似的东西:
@filtered_products = Product.all
...
if params[:product_categories].present?
@filtered_products = @filtered_products.where(category_id: params[:product_categories].map(&:to_i))
end
...
#etc
Run Code Online (Sandbox Code Playgroud)
但是,由于单击时无法取消选择多选,因此有一个空白选项.但是,当设置此选项时,params[:product_categories]包含[""].这导致if语句被评估,并且作为".to_i == 0,我们只获得类别为0的产品(通常为none,因为ActiveRecord在数据库中从1开始id).这不是理想的结果,因为实际上我们想要选择空白选项时的所有产品.
处理这种情况变得更加困难,因为可能意外地选择空白选项和一个或多个其他选项.所以这种情况也需要处理.
我已将if语句更改为
if params[:product_categories].present? && params[:product_categories].any? && (params[:product_categories].length > 1 || params[:product_categories].first != "")
...
end
Run Code Online (Sandbox Code Playgroud)
它有效,但这段代码非常难看.我想知道是否有更好,更干,更Rails的方式来做到这一点.