通过表单输入过滤显示的记录

时间:2011-01-26 19:18:16

标签: ruby-on-rails activerecord filtering

我是编程的新手,再次陷入困境,

我正在使用rails 3并且目前有一个场地模型,其中每个场地属于一个区域和一个类型(每个都是他们自己的模型)数据库中的所有场所都显示在索引页面的分区中显示场地名称,面积和类型。

如何在索引页面上创建一个包含2个下拉列表(区域和类型)的表单,该表单根据下拉列表中选择的内容过滤显示的场地记录。例如选择酒吧作为类型和曼彻斯特作为区域,只显示曼彻斯特的酒吧或选择酒吧作为类型和所有区域和所有区域的所有酒吧显示。

我已经尝试过安装sphinx和thinking_sphinx,但似乎无法让它们在我的Windows 7上工作。我在服务启动时遇到了1067错误,并且“无法启动searchd守护程序”。来自think_sphinx on rake ts:start,我假设是来自服务器没有运行,所以我希望这个问题的答案不会涉及sphinx。

我已经看过范围,并且我认为这可能是要走的路?虽然我没有第一个想法如何包含一个下拉列表来选择所需的范围,或者实际上如何编写一个范围来满足我想要的那种过滤器。

非常感谢任何帮助,非常感谢!

3 个答案:

答案 0 :(得分:1)

在你的控制器中,你应该能够做一些简单的事情:

@filtered_venues = Venue.where(:area => params[:venue][:area], :type => params[:venue][:type]).all

这应该可以为您提供所需的过滤结果。

然后在您的视图中,您应该能够使用表单助手来创建选择元素:

select("venue", "area", ['New York', 'London', 'Amsterdam'], {}, { :prompt => 'Select Area' })
select("venue", "type", ['Pub', 'Outdoor', 'Hall'], {}, { :prompt => 'Select Type' })

应输出如下内容:

  <select name="venue[area]">
    <option value="">Select Area</option>
    <option value="New York">New York</option>
    <option value="London">London</option>
    <option value="Amsterdam">Amsterdam</option>
  </select>
  <select name="venue[:type]">
    <option value="">Select Type</option>
    <option value="Pub">Pub</option>
    <option value="Outdoor">Outdoor</option>
    <option value="Hall">Hall</option>
  </select>

如果您准备好区域或类型的集合,还有很多其他方法可以动态获取选项。有关详细信息,请查看以下内容:http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html

答案 1 :(得分:0)

这种类型的过滤可以在JavaScript,Ruby或两者中完成。

如果HTML本身包含确定哪些项与哪些过滤器匹配所需的所有元数据,则可以通过隐藏和显示元素以响应表单中的更改来完全在JavaScript中完成。

如果要求用户单击其所选过滤器的提交按钮才能生效,则表单可以简单地提交,您可以使用Rails在后端重新填充表单。

如果HTML没有所有元数据并且您不希望他们必须提交表单,您可以使用AJAX将选定的过滤器发送到后端,让Rails构造新表单并发送它返回客户端,然后使用JavaScript更新前端。

您可以从Railscasts剧集Search, Sort, Paginate with AJAX中获得一些想法。这不完全是你的情况,但它可能会指出你正确的方向,这些类型的操作如何工作。

答案 2 :(得分:0)

您可以通过多种方式执行此操作,具体取决于您希望过滤的具体方式。最好的方法是将过滤器构建为.find(:conditions => ...)调用,让数据库完成繁重的工作。如果您事先不知道要过滤哪些参数,那么在代码中执行此操作会更容易但效率更低。假设您有搜索参数venue_areavenue_type,您可以在控制器中执行以下操作:

def index
  @venues = Venue.all # Or whatever criteria you might have here
  @venues = @venues.select { |v| v.area_id == params[:venue_area] } if !params[:venue_area].blank?
  @venues = @venues.select { |v| v.type_id == params[:venue_type] } if !params[:venue_type].blank?
  ...
end

然后,您可以在搜索表单中创建包含所有类型和区域ID的下拉列表:s。您可以使用几个帮助程序,例如select_tag。当然,@options会更好地填充在控制器中,但这表明关系更清晰:

<form method="get">
<% @options = Area.all.map { |a| [ a.name, a.id ] } %>
<%= select_tag("venue_area", options_for_select(@options)) %>
<input type="submit" value="Filter" />
</form>