Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在RubyonRails中输出分层列表_Ruby On Rails_Ruby_Hierarchy - Fatal编程技术网

Ruby on rails 如何在RubyonRails中输出分层列表

Ruby on rails 如何在RubyonRails中输出分层列表,ruby-on-rails,ruby,hierarchy,Ruby On Rails,Ruby,Hierarchy,当一个页面可以是另一个页面的父页面时,我有一个页面的层次结构。页面存储在具有以下结构的DB表中: page.id page.name page.parent\u id 现在我需要输出一个分层列表,如下所示: A页 B页 C页 D页 等 E页 此外,对多个级别也没有限制 在RoR中实现这一目标的最佳方法是什么?提前谢谢。嗨,我会用一些宝石来做这个 i、 e 嗨,我会用一些宝石来做这件事 i、 e 假设代码,未验证 class Page < ActiveReco

当一个页面可以是另一个页面的父页面时,我有一个页面的层次结构。页面存储在具有以下结构的DB表中:

  • page.id
  • page.name
  • page.parent\u id
现在我需要输出一个分层列表,如下所示:

  • A页
    • B页
    • C页
      • D页
  • E页
此外,对多个级别也没有限制


在RoR中实现这一目标的最佳方法是什么?提前谢谢。

嗨,我会用一些宝石来做这个

i、 e


嗨,我会用一些宝石来做这件事

i、 e


假设代码,未验证

class Page < ActiveRecord::Base
  has_many :children, class_name: 'Page', foreign_key: 'parent_id'
  belongs_to :parent, class_name: 'Page'
end

# Helper
def tree_list(collection)
  content_tag :ul do
    collection.each do |item|
      if item.children.blank?
        content_tag :li do
          item.name
        end
      else
        tree_list(item)
      end
    end
  end 
end

# View
tree_list(Page.all)
class页面

基本思想是
tree\u list
方法将生成一个递归列表,直到某个页面没有子页面。

假设代码,未验证

class Page < ActiveRecord::Base
  has_many :children, class_name: 'Page', foreign_key: 'parent_id'
  belongs_to :parent, class_name: 'Page'
end

# Helper
def tree_list(collection)
  content_tag :ul do
    collection.each do |item|
      if item.children.blank?
        content_tag :li do
          item.name
        end
      else
        tree_list(item)
      end
    end
  end 
end

# View
tree_list(Page.all)
class页面

基本思想是
tree\u list
方法将创建一个递归列表,直到某个页面没有子页面为止。

正如另一个用户所建议的,您可以使用
estority
gem,但它需要更改您的数据库。如果不能这样做,则应创建一个有向无环图,并为每个节点设置深度

class Page < ActiveRecord::Base
  attr_accessor :depth

  def children
    @children ||= []
  end
end

# Loading required pages in single query, add predicate if needed
pages = Page.includes(:parent).all

# Setting up a hash table to find pages in constant time
page_index = pages.reduce({}){|acc, page| acc[page.id] = page}

# Setting up children
pages.each do |page|
  if page.parent_id
    page_index[page.parent_id].children << page
  end
end

# Basic depth-first search routine
def dfs(page, visited, depth)
  page.depth = depth
  visited[page.id] = true
  page.children.select{|p| visited[p] == nil}.each{|p| dfs(p, visited, depth + 1)}
end

# Performing depth-first search for each connected component
visited = {}
pages.each do |page|
  if visited[page.id] == nil
    dfs(page, visited, 0)
  end
end
class页面page_index[page.parent_id].children正如另一位用户所建议的,您可以使用
祖先
gem,但它需要更改您的数据库。如果不能这样做,则应创建一个有向无环图,并为每个节点设置深度

class Page < ActiveRecord::Base
  attr_accessor :depth

  def children
    @children ||= []
  end
end

# Loading required pages in single query, add predicate if needed
pages = Page.includes(:parent).all

# Setting up a hash table to find pages in constant time
page_index = pages.reduce({}){|acc, page| acc[page.id] = page}

# Setting up children
pages.each do |page|
  if page.parent_id
    page_index[page.parent_id].children << page
  end
end

# Basic depth-first search routine
def dfs(page, visited, depth)
  page.depth = depth
  visited[page.id] = true
  page.children.select{|p| visited[p] == nil}.each{|p| dfs(p, visited, depth + 1)}
end

# Performing depth-first search for each connected component
visited = {}
pages.each do |page|
  if visited[page.id] == nil
    dfs(page, visited, 0)
  end
end
class页面页面索引[page.parent\u id]。儿童以下是要处理的最佳实践-

简单的桌子

Table Emp
id: Integer
name: String
parent_id: Integer
联想

app/models/emp.rb
class Emp < ApplicationRecord
  has_many :subs, class_name: 'Emp', foreign_key: :parent_id
  belongs_to :superior, class_name: 'Emp', foreign_key: :parent_id
end
app/models/emp.rb
类Emp
范围定义

class Emp < ApplicationRecord
  ----
  ----
  scope :roots, -> { where(parent_id: nil) }
end
class Emp{where(parent_id:nil)}
结束
获取数据

def tree_data
  output = []
  Emp.roots.each do |emp|
    output << data(emp)
  end
  output.to_json
end
def data(employee)
  subordinates = []
  unless employee.subs.blank?
    employee.subs.each do |emp|
      subordinates << data(emp)
    end
  end
  {name: employee.name, subordinates: subordinates}
end
def树_数据
输出=[]
Emp.root.each do | Emp|

输出以下是要处理的最佳实践-

简单的桌子

Table Emp
id: Integer
name: String
parent_id: Integer
联想

app/models/emp.rb
class Emp < ApplicationRecord
  has_many :subs, class_name: 'Emp', foreign_key: :parent_id
  belongs_to :superior, class_name: 'Emp', foreign_key: :parent_id
end
app/models/emp.rb
类Emp
范围定义

class Emp < ApplicationRecord
  ----
  ----
  scope :roots, -> { where(parent_id: nil) }
end
class Emp{where(parent_id:nil)}
结束
获取数据

def tree_data
  output = []
  Emp.roots.each do |emp|
    output << data(emp)
  end
  output.to_json
end
def data(employee)
  subordinates = []
  unless employee.subs.blank?
    employee.subs.each do |emp|
      subordinates << data(emp)
    end
  end
  {name: employee.name, subordinates: subordinates}
end
<代码>def树\u数据 输出=[] Emp.root.each do | Emp|
输出谢谢,我尝试了一下,它成功了!不过有两个增强功能:1)嵌套的content_标记违反直觉。有关详细信息,请参见此链接:;2) 我稍微修改了代码:
def tree_list(collection)content_tag(:ul)do collection.each do | item | concat(content_tag(:li,item.name))if!item.children.blank?concat(tree_list(item.children))end
这是一个有效的版本。虽然这种方法有效,但我很可能会坚持使用现有的gem,以避免重新发明轮子。无论如何,谢谢你的建议!这取决于用例,而不是发明轮子。如果只用一种方法就能解决我的问题,我绝对不会去买宝石。这是简单的基本原则。谢谢,我试了一下,它成功了!不过有两个增强功能:1)嵌套的content_标记违反直觉。有关详细信息,请参见此链接:;2) 我稍微修改了代码:
def tree_list(collection)content_tag(:ul)do collection.each do | item | concat(content_tag(:li,item.name))if!item.children.blank?concat(tree_list(item.children))end
这是一个有效的版本。虽然这种方法有效,但我很可能会坚持使用现有的gem,以避免重新发明轮子。无论如何,谢谢你的建议!这取决于用例,而不是发明轮子。如果只使用一种方法可以解决我的问题,我肯定不会去创业板。这是简单的基本原则。谢谢你让我知道这个宝石。我是Ruby和Rails新手,不知道所有可能的选项。我会给它一个