【发布时间】:2012-11-27 08:29:50
【问题描述】:
我有一张如下表
好吧,在这个表中,每个用户都有一个父用户,那么如果我们选择一个用户,那么它的 id 、children ids 和 children ids 应该作为数组返回。我需要一个查询来在 rails 中获取这个值而不使用任何宝石。感谢您的帮助:->
【问题讨论】:
标签: mysql ruby-on-rails-3 rubygems
我有一张如下表
好吧,在这个表中,每个用户都有一个父用户,那么如果我们选择一个用户,那么它的 id 、children ids 和 children ids 应该作为数组返回。我需要一个查询来在 rails 中获取这个值而不使用任何宝石。感谢您的帮助:->
【问题讨论】:
标签: mysql ruby-on-rails-3 rubygems
class User << ActiveRecord::Base
def self.build_tree(reverse=false)
g = Array.new
self.find(:all).each do |p|
if reverse
g << [p.id,p.parent]
else
g << [p.parent,p.id]
end
end
g
end
def self.subordinates(man_id)
g = self.build_tree false
g.map{|i| i[1] if i[0]==man_id.to_i}.compact
end
def self.superiors(user_id)
g = self.build_tree true
g.map{|i| i[1] if i[0]==user_id.to_i}.compact
end
end
当调用 Superiors(parents) 或 Subordinates(childrends) 时,它会给出所需的结果
例如:- [2,4,6,8]
如果您想获得 children->childrends 或 parent->parents,只需执行 iterate 调用函数上级或下级 strong> 直到得到 nil 或 [] 数组。
【讨论】:
您正在陷入 SQL 反模式。对这样构造的树执行操作是非常低效的。我并不是说您应该为此使用 gem,而是考虑使用一些更智能的方法来保存这些数据(搜索 sql tree structure 应该会产生一些有意义的结果)。
您要查找的查询需要两个自连接:
SELECT t1.id user_ids, t2.id children_ids, t3.id children_children_ids FROM users t1
LEFT JOIN users t2 ON t2.parent = t1.id
LEFT JOIN users t3 ON t3.parent = t2.id
另一方面,如果您的 Rails 模型定义了自关系,您可以轻松编写:
user.children #=> (array of children)
user.children.flat_map(&:children) #=> (array of grandchildren)
此关系的定义应如下所示:
class User << ActiveRecord::Base
has_many :children, class_name: User, foreign_key: 'parent'
end
【讨论】:
table改成你的表名(我相信是users)