使用复选框筛选记录

Dav*_*ave 5 checkbox filtering ruby-on-rails

我正在尝试从零编程经验中学习rails并且有一个我试图制作的应用程序.在这里的人们的帮助下,我有一个场地的索引页面,可以通过下拉菜单过滤它们所属的区域.我希望能够产生相同的效果,但使用复选框,并且还能够选择多个区域添加到过滤器.这是我到目前为止:

型号:

class Venue < ActiveRecord::Base
  belongs_to :user
  has_many :reviews
  belongs_to :area

  scope :north, where(:area_id => "2")
  scope :west, where(:area_id => "3")
  scope :south, where(:area_id => "4")
end
Run Code Online (Sandbox Code Playgroud)

控制器:

def index
  if (params[:area] && Area.all.collect(&:name).include?(params[:area][:name]))
    @venues = Venue.send(params[:area][:name].downcase)
  else
    @venues = Venue.all
  end
end
Run Code Online (Sandbox Code Playgroud)

场地index.html.erb:

<div class="filter_options_container">

  <form class="filter_form", method="get">
    <%= select("area", "name", Area.all.collect(&:name), {:prompt => 'All Areas'}) %><br>
    <input type="submit" value="Filter" />
  </form>

  <br><br>

  <form class="filter_form", method="get">
    <% Area.find(:all).each do |a| %>
      <%= check_box_tag("area", "name") %>
      <%= a.name %>
    <% end %>
    <input type="submit" value="Filter" />
  </form>
</div>

<div class="venue_partials_container">
  <%= render :partial => 'venue', :collection => @venues %>
  <div class="clearall"></div>
  <%= link_to 'add a new venue', new_venue_path, :class => "add_new_venue_button" %>
</div>
Run Code Online (Sandbox Code Playgroud)

filter_options_container中的第一个表单(下拉列表)工作正常,但复选框(第二个表单)返回"无法将符号转换为整数",我错过了什么/做错了什么?

感谢您的任何帮助.

Xav*_*olt 8

我不知道究竟是什么导致了您的错误,但我可以告诉您check_box_tag帮助程序没有按照您期望的方式工作.从文档中,它的定义如下:

check_box_tag(name, value = "1", checked = false, options = {})
Run Code Online (Sandbox Code Playgroud)

因此check_box_tag("area", "name")反复呼叫只会给你<input id="area" name="area" type="checkbox" value="name" />多次.请注意,"value"属性(在提交该表单时发送到您的服务器的值)始终是"名称" - 不是您想要的!

相反,请尝试以下方法:

<% Area.all.each do |a| %>
    <%= check_box_tag("areas[]", a.id) %>
    <%=h a.name %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

我改变的事情:

  1. 我用它Area.all代替Area.find(:all)- 我是出于美观原因而做的,但是DanneManne的回答声称它在Rails 3中已经过时了(我不知道 - 我仍然在2.3.8).
  2. 我在值字段中使用了区域的ID而不是其名称; 如果可以的话,通过ID查找内容总是好的--ID是整数,并且比字符串更快地比较,并且数据库中的id列总会有一个索引用于超快速查找.
  3. 最后,但最重要的是我在[]输入名称之后输入了.这使得Rails可以将使用此名称提交的所有值收集到一个数组中,而不是仅仅使用最后一个.见下文:

扔掉网址......

/whatever?a=3&a=17&a=12
Run Code Online (Sandbox Code Playgroud)

...在Rails应用程序中为您提供params哈希...

{:a => 12}
Run Code Online (Sandbox Code Playgroud)

......但是网址......

/whatever?a[]=3&a[]=17&a[]=12
Run Code Online (Sandbox Code Playgroud)

...给你你想要的东西:

{:a => [3, 17, 12]}
Run Code Online (Sandbox Code Playgroud)

如果你有所有你感兴趣的,你可以得到一切都在场馆area_ids数组任何在一个班轮这些领域的(是不是Rails的伟大?):

filtered_venues = Venue.all(:conditions => {:area_id => params[:areas]})
Run Code Online (Sandbox Code Playgroud)

在调用该查找器之前,请确保您有一个有效的区域ID数组 - 如果不这样做,您的条件哈希值将评估为{:area_id => nil},并且Rails会找到所有没有的场所area_id - 可能没有,绝对不是你想要的.

希望这可以帮助!