使用 Awesome_nested_set 按字母顺序排序类别选择菜单

发布于 2024-10-08 10:40:50 字数 646 浏览 4 评论 0原文

使用Rails 3 中的awesome_nested_set,我创建了一个分层类别系统。为了在视图中显示类别选择器,我使用了以下代码:

<%= form.select :parent_id, options_for_select(nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" }.unshift(["No Parent", nil]), @category.parent_id) %>

我正在尝试按字母顺序对类别进行排序,逐级为基础。如果我将nested_set_options(Category,@category)更改为nested_set_options(Category.order(“name”),@category)这将按名称重新排序整个类别列表;我想要做的是按名称字母顺序对每个节点的子节点重新排序。

例如,我希望结果选择菜单的顺序如下:

Animal
- Bird
-- Chicken
-- Hawk
- Fish
-- Cod
-- Goldfish
-- Trout
- Mammal
-- Cat
-- Primate
--- Chimpanzee
--- Human
-- Zebra
Plant
- Tree

Using awesome_nested_set with Rails 3, I've created a hierarchical categories system. To display the category selector in the view, I've used the following code:

<%= form.select :parent_id, options_for_select(nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" }.unshift(["No Parent", nil]), @category.parent_id) %>

I'm attempting to order the categories in alphabetical order, on a level by level basis. If I change the nested_set_options(Category, @category) to nested_set_options(Category.order("name"), @category) this will reorder the whole categories list by name; what I want to do is reorder the children of each node alphabetically by name.

For example, I want to resulting select menu to be ordered like this:

Animal
- Bird
-- Chicken
-- Hawk
- Fish
-- Cod
-- Goldfish
-- Trout
- Mammal
-- Cat
-- Primate
--- Chimpanzee
--- Human
-- Zebra
Plant
- Tree

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝颜夕 2024-10-15 10:40:51

虽然我不熟悉 Awesome_nested_set,但您可以在 Rails 3 中调用 order 两次。

Category.order(:level).order(:name)

这应该按每个级别对类别进行排序,然后按每个级别中的名称进行排序。另外,您可以将其放在模型内的默认范围内。

class Category < ActiveRecord::Base
  default_scope order('level, name')
  ...
end

订单非常适合默认范围,因为它们不会影响任何默认值。

Although I am unfamiliar with awesome_nested_set, you can call order twice in Rails 3.

Category.order(:level).order(:name)

This should order Category by each level and then by name within each level. Also, you can throw this on the default scope within the model.

class Category < ActiveRecord::Base
  default_scope order('level, name')
  ...
end

Orders are great for default scope because they don't effect any default values.

桃扇骨 2024-10-15 10:40:51

您可以按照此 stackoverflow 帖子中的建议使用 @item.children. except(:order).order("your_sort_column")很棒的嵌套设置顺序

You can use @item.children.except(:order).order("your_sort_column") as suggested in this stackoverflow post: awesome nested set order by

独行侠 2024-10-15 10:40:51

我有同样的问题。我按照此处所述解决了这个问题。基本上将以下方法添加到模型中,acts_as_nested_set 允许您通过调用 @category.sorted_heir_list 来返回视图中选择标记的对象的平面数组:

  def sorted_heir_list(target = self, set = self.descendants)
    sorted_list = [target]
    kids = set.select{|i| i.parent_id == target.id}.sort_by{|j| j.name}
    kids.each do |k|
      sorted_list.concat(sorted_heir_list(k, set))
    end
    sorted_list
  end

我比其他答案更喜欢这种方法我在评论中链接了 Morgan Christiansson 的答案,因为它只产生一次 DB 命中(相对于其他方法的 N 次命中)。

I had the same issue. I solved it as described here. Basically adding the below method to the model that acts_as_nested_set allows you to return a flat array of objects for the select tag in the view by calling @category.sorted_heir_list:

  def sorted_heir_list(target = self, set = self.descendants)
    sorted_list = [target]
    kids = set.select{|i| i.parent_id == target.id}.sort_by{|j| j.name}
    kids.each do |k|
      sorted_list.concat(sorted_heir_list(k, set))
    end
    sorted_list
  end

I like this method better than the other answer that I linked in my comment on Morgan Christiansson's answer because it only incurs a single DB hit (vs. N hits with the other approach).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文