Rails rails 无限级分类实现 ok,请教一个小问题

flowerwrong · 2014年07月04日 · 最后由 flowerwrong 回复于 2014年07月05日 · 3608 次阅读

我基于 ORM 自关联实现了一个无限级分类,貌似都 ok,但最后在显示的时候遇到一点小问题,求解。 一.先上 model 字段有三个,id name parent_id

class Cat < ActiveRecord::Base
    belongs_to :parent, :class_name => "Cat", :foreign_key => "parent_id"
    has_many :childs, :class_name => "Cat", :foreign_key => "parent_id"
end

二.controller index,目的是显示所有分类

def index
  @cats = Cat.where :parent_id => 0
end

三.view index

<ul>
  <% @cats.each do |cat| %>
    <li>
      <%= cat.name %><%= CatsHelper.get_children(cat) %>
    </li>
  <% end %>
</ul>

四.helper 目的是获取子分类,并 html 化,调用是 view 里面的<%= CatsHelper.get_children(cat) %>

module CatsHelper
  def self.get_children(cat)
    if cat.childs != []
      cat_tree = "<ul>"
      cat.childs.each do |cat|
        cat_tree += "<li>#{cat.name}"
        CatsHelper.get_children(cat)
        cat_tree += "</li>"
      end
      cat_tree += "</ul>"
      return cat_tree
    end
  end
end

五.显示结果 他的 html 标签还在,没有解析,这是为什么?怎么解决呢?谢谢

#1 楼 @Peter 左右值算法,可是我还是想问问那个怎么使得<%= CatsHelper.get_children(cat) %>可以解析

#2 楼 @flowerwrong <%= raw CatsHelper.get_children(cat) %>

#4 楼 @flowerwrong 要不要这样试一下, 我没测试,看你写的类方法,所以给出一点小建议!☺

raw 方法其实是不安全的, 应该用 sanitize 详见: 别用 raw 和 html_safe

module CatsHelper

  def cat_get_children cat
      return unless cat.is_a?(Cat) || cat.childs.present?
      content_tag(:ul, class: 'cat-ul') do
         cat.childs.map do |cat|
             content_tag(:li, class: 'cat-ul-li') do
                cat.name
                get_children cat
             end
          end
      end
  end

end
<ul>
   <% @cats.each do |cat| %>
     <li>
        <%= cat.name %>
        <%= sanitize cat_get_children(cat) %>
     </li>
   <% end %>
 </ul>

#5 楼 @mystery I don't know why it doesn't work. It return <ul class="cat-ul"></ul> only in my index.html, and no more.

简单的实现二级分类该怎么写 数据结构是这样的:

CREATE TABLE `boards` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `parent_id` int(11) NOT NULL DEFAULT '0',
   `name` varchar(255) DEFAULT NULL,
   `created_at` datetime NOT NULL,
   `updated_at` datetime NOT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8

具体实现原理请看 #1 楼 的两个链接

#7 楼 @lixiaolun 我的数据库就是这样的,一楼那个是左右值算法(google 之),和这种 parent_id 的做法各有优缺点。简单的二级分类可以直接两个表(子表和父表),我看很多类似 ruby-china 的论坛都是这么做的,例如http://f2e.im/ (python 的)

#9 楼 @flowerwrong 你的提示突然让我想起个问题 像我这种表形式 一个表当成 2 个表用 each 两次 第一次包含第二次

需要 登录 后方可回复, 如果你还没有账号请 注册新账号