select_tag with acts_as_tree

Posted by devon on December 22nd, 2007 filed in Rails应用

目标:在Rails中实现多级的下拉选择框,效果如下图所示。

方案:select_tag + option_groups_from_collection_for_select + acts_as_tree。
在数据库中有 category 表,该表使用 acts_as_tree 实现多级结构。基于 rails2.0.2 与 acts_as_tree 插件。

1,创建 category 表,使用 acts_as_tree

<code>
script/generate model category
</code>

在migration中

1
2
3
4
5
create_table :categories do |t|
  t.string :name, :limit =&gt; 16
  t.integer :parent_id
  t.timestamps
end

rake db:migrate 生成 category 表。

安装 acts_as_tree 插件,在model中声明 acts_as_tree:

<code>
script/plugin install acts_as_tree
</code>
1
2
3
class Category &lt; ActiveRecord::Base
acts_as_tree
end

在数据库上插入示例数据。其中几项的 parent_id 指向表中的其它记录。

2,Patch option_groups_from_collection_for_select
rails 库中的 option_groups_from_collection_for_select 还不能达到这种效果,所以,需要对该方法做一点小修改。在application_helper.rb 的未尾加上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module ActionView
  module Helpers
    module FormOptionsHelper
      def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
        collection.inject("") do |options_for_select, group|
          group_label_string = eval("group.#{group_label_method}")
          if group.send(group_method).blank?
            options_for_select += options_for_select(group.send(option_value_method) => group.send(option_key_method))
          else
            options_for_select += "'
          end
        end
      end
    end
  end
end

3,利用 select_tag 生成 view

<code>
<%= select_tag :cagegory_id, option_groups_from_collection_for_select(Category.find_all_by_parent_id(nil), :children, :name, :id, :name) %>
</code>

如果需要一个空值:

<code>
<%= select_tag :cagegory_id, options_for_select(['']) + option_groups_from_collection_for_select(Category.find_all_by_parent_id(nil), :children, :name, :id, :name) %>
</code>

参考:
Acts As Tree
Api for FormOptionsHelper

Related posts:

  1. rails中联级菜单的一种实现方式 通过Ajax实现联级菜单。 典型应用场景:两个下拉框(select),第一是省份的选择,第二个是城市的选择。在省份选择定之后,第二个select显示选中省份对应的城市。也就是说城市要根据所选的省份过滤。 实现方式:在切换省份的同时,向server端请求对应省份下的city,生成select HTML代码替换原city select, 具体如下。view中: 省份: remote_function(:with => "'province_id='...

Related posts brought to you by Yet Another Related Posts Plugin.

Leave a Comment