我对rails非常陌生,而且我对这个问题的逻辑很不满意。
我有一个员工表(使用mysql),每个员工都有一个manager_id
键,用于指向他们报告的员工。例如,标题为“CEO”且ID为1的员工的manager_id为nil,标题为“CTO”的员工的manager_id为1.所以我的记录看起来像这样
id: 1, first_name: "Bob", last_name: "Boss", title: "CEO", manager_id: null
id: 2, first_name: "Pat", last_name: "Guy", title: "CTO", manager_id: 1
id: 3, first_name: "John", last_name: "Dude", title: "VP of engineering", manager_id: 2
我的JSON结构应如下所示
[
{id: 1, first_name: "Bob", last_name: "Boss", title: "CEO", manager_id: null, descendents: [
{id: 2, first_name: "Pat", last_name: "Guy", title: "CTO", manager_id: 1, descendents: [
{id: 3, first_name: "John", last_name: "Dude", title: "VP of engineering", manager_id: 2, descendents: [....]}
]},
{..more CEO descendents...}
]
我正在尝试创建一个从CEO开始的嵌套JSON结构,列出向他们报告的所有员工,以及每个员工的后代。我试图写一个创建这个的脚本,但我一直在进行无限的递归调用。这就是我所拥有的
#start at some root
@root = Employee.find_by title: 'CEO'
#convert to hash table
@results[0] = @root.attributes
#add direct_reports key
@results[0]["direct_reports"] = []
def getBelow(root=@root)
@reports = Employee.where("manager_id = ?", @root[:id])
if @reports.blank?
return []
else
@reports = @reports.map(&:attributes)
@reports.each do |person|
person["direct_reports"] = []
getBelow(person)
end
@reports = Employee.where("manager_id = ?", @root[:id])
root["direct_reports"] = @reports
end
return @root
end
@list = getBelow(@results[0])
如果我传入每个新人物,那么当@reports.blank?
变为真时,它们最终是否应该结束?
我想到的另一个选择是使用受此博客文章启发的表格关联
https://hashrocket.com/blog/posts/recursive-sql-in-activerecord
但这看起来有点太复杂了。
答案 0 :(得分:0)
getBelow方法中的一些问题
您总是使用@root,而不是使用param(root)。所以你总是从'CEO'开始。
您正在递归调用getBelow,但未使用结果。
您拨打@reports = Employee.where("manager_id = ?", @root[:id])
两次。
您返回@root。
正如Jorge Najera所说,有些宝石很容易处理树状结构。如果你想自己构建它,这是我的建议:
#start at some root
@root = Employee.find_by manager_id: nil
#convert to hash table
@tree = @root.attributes
#add direct_reports key
@tree["direct_reports"] = getBelow(@root)
def getBelow(manager)
branch = []
Employee.where("manager_id = ?", manager.id).each do |employee|
node = employee.attributes
node["direct_reports"] = getBelow(employee)
branch << node
end
branch
end
这没有经过测试,所以我认为你会遇到一些错误,但我相信这个想法很好。