【问题标题】:Using checkboxes to filter records使用复选框过滤记录
【发布时间】:2011-06-19 16:09:31
【问题描述】:

我正在尝试从零编程经验中学习 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

控制器:

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

场地 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>

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

感谢您的帮助。

【问题讨论】:

    标签: ruby-on-rails checkbox filtering


    【解决方案1】:

    我不知道究竟是什么导致了您的错误,但我可以告诉您,check_box_tag 助手没有按照您期望的方式工作。从the documentation,定义如下:

    check_box_tag(name, value = "1", checked = false, options = {})
    

    所以反复调用check_box_tag("area", "name") 只会给你&lt;input id="area" name="area" type="checkbox" value="name" /&gt; 多次。请注意,“值”属性(即在提交表单时发送到您的服务器的值)始终是“名称”——不是您想要的!

    请尝试以下方法:

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

    我改变的东西:

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

    正在抛出 URL...

    /whatever?a=3&a=17&a=12
    

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

    {:a => 12}
    

    ...但是网址...

    /whatever?a[]=3&a[]=17&a[]=12
    

    ...给你你想要的:

    {:a => [3, 17, 12]}
    

    如果您有所有感兴趣的 area_id 数组,您可以在单行中获取这些区域中任何中的所有场所(Rails 不是很棒吗? ?):

    filtered_venues = Venue.all(:conditions => {:area_id => params[:areas]})
    

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

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      在您对 Area.find 的调用中,您提供了参数 :all。我假设您正在使用此语法在 Rails 3 中已弃用。 find(:all, ...) 或 find(:first, ...) 等所有以前的用法都不能再使用了。相反,您应该像第一种形式一样使用它:Area.all(...)

      附带说明一下,check_box_tag 参数看起来也可能是错误的。我猜你应该发送 a.name 而不是“name”。

      这是我认为可行的修改形式:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-06
        • 2013-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多