Rails: 使用多选过滤器的空选项

18 浏览
0 Comments

Rails: 使用多选过滤器的空选项

这是一个我经常遇到的问题。让我用一个简化的例子来解释一下:

假设我想展示一个搜索页面,用户可以通过选择一个或多个产品类别来过滤结果。在视图中,代码如下:

<%= select_tag("product_categories", options_from_collection_for_select(@product_categories, 'id', 'name'), multiple:true, include_blank:"(所有类别)" %>

现在,在控制器中,我有类似这样的代码:

@filtered_products = Product.all
...
if params[:product_categories].present? 
   @filtered_products = @filtered_products.where(category_id: params[:product_categories].map(&:to_i))
end
...
#等等

然而,由于无法取消多选选项,所以有一个空选项。但是,当设置了这个选项时,params[:product_categories]中包含了[""]。这导致了if语句的判断结果为真,由于"".to_i == 0,我们只会得到类别为0的产品(通常是没有类别的,因为ActiveRecord在数据库中从1开始编号)。这不是期望的结果,实际上当选择了空选项时,我们希望得到所有产品。

处理这种情况更加困难的原因是,可能会意外地同时选择空选项和其他一个或多个选项。因此,这种情况也需要处理。

我已经将if语句改为了:

if params[:product_categories].present? && params[:product_categories].any? && (params[:product_categories].length > 1 || params[:product_categories].first != "")
   ...
end

这个代码是可行的,但是非常丑陋。我想知道是否有一种更好、更DRY、更符合Rails风格的方法来实现这个功能。

0
0 Comments

Rails: multiselect过滤器带有空选项的问题

问题的出现原因:

在Rails中,当使用多选过滤器时,有时需要包含一个空选项,以便用户可以选择不过滤任何内容。然而,在Florin的回答中,可能会出现一个问题:即使没有选择任何选项,空选项也会被包含在params[:product_categories]中,导致过滤器无法正常工作。

解决方法:

为了解决这个问题,可以使用以下代码来过滤空选项:

params[:product_categories].reject!(&:empty?) if params[:product_categories].length > 1

这段代码会检查params[:product_categories]中的每个元素是否为空,并将空元素从数组中删除。然后,通过判断params[:product_categories]的长度是否大于1,来确定是否选择了多个选项。只有在选择了多个选项时,才会执行过滤器。

这样,就可以确保空选项不会干扰过滤器的正常工作,同时还能让用户选择不过滤任何内容。

0
0 Comments

问题出现的原因是在Rails中使用多选筛选时,希望能够有一个空选项。然而,上述代码并不能实现这个功能。解决方法如下:

# 在视图中添加一个空选项
<%= select_tag 'product_categories[]', options_for_select([['', '']] + ProductCategory.all.map { |p| [p.name, p.id] }), multiple: true %>
# 在控制器中处理选择的筛选项
if params[:product_categories].reject!(&:empty?).any?
  # 处理非空选项的逻辑
end

0
0 Comments

Rails: multiselect过滤器带有空选项的问题

当您没有选择任何类别时,您可以添加与product_categories相同的hidden_field,以避免在选择选项之前带有空值[""]

<%= hidden_field_tag "product_categories" %>
<%= select_tag("product_categories", options_from_collection_for_select(_categories, 'id', 'name'), multiple:true, include_blank:"(all categories)" %>

然后处理它。它不需要使用map(&:id),因为""会自动转换为0。

if params[:product_categories] != [""]
   _products = _products.where(category_id: params[:product_categories])
end

这就是为什么嵌入数组始终显示在多选选项中的原因。我希望这能简化您的代码。

来源链接:[https://stackoverflow.com/questions/8929230](https://stackoverflow.com/questions/8929230)

0