我有一个Business
模型:belongs_to Category
类别的示例层次结构:
我对acts_as_tree
层次结构使用Category
。
如何找到餐馆类别下的所有Businesses
?
答案 0 :(得分:2)
如果您希望获得树状层次结构中节点的所有后代,您有两个选择:
使用经典acts_as_tree
,预加载所选类别,开始查询的级联来检索所有的孩子,孙子等,直到你得到的只是叶(节点没有进一步chidren)。这种方法听起来很不错。
使用更高级的树表示,如嵌套集或闭包树。在这些表示下,您只需一个查询即可获取特定节点的所有后代。
然后,您可以在“企业”中获取收集的类别和查询:
Business.where(:category => categories)
(技术说明:嵌套设置)
在一组嵌套的表示,每个节点有两个指标,以下列方式分配:想象,每个节点有两个窗口,东,西一个房子,树就像是一个分叉的道路,所有的孩子都比较或少于他们父母的北方。所以你从根屋的东边开始,在你遇到的窗户上放一个序号。你永远不会越过任何道路,你只能绕过没有通往北方的道路的房屋。最后,你将再次进入根屋,并在西窗口放一个数字。
分配的号码将具有以下属性:
因此,虽然在树中插入一个新元素是昂贵的(它需要更新一些索引),检索整个下降(所有子孙,......)非常容易,只需取“其节点”东部“和”西部“数字在您选择的类别的东部和西部之间。你可以稍微做得更好,但这并不重要。
像https://github.com/collectiveidea/awesome_nested_set这样的图书馆将为您管理所有这些内容,您只需拨打
categories = @category.self_and_descendants.to_a
(技术说明:关闭树)
此方法需要一个附件表,您可以在其中存储child->parent
关系的传递闭包(请参阅http://en.wikipedia.org/wiki/Reflexive_transitive_closure#P_closures_of_binary_relations)
该表将包含所有对祖先后代,因此您可以以智能方式与该表连接,以获得几乎任何层次结构的切片。
同样,像https://github.com/mceachen/closure_tree这样的图书馆将为您完成艰苦的工作,您将能够做到
categories = @category.self_and_descendants.to_a
答案 1 :(得分:0)
category = Category.find_by_name("Restaurants")
然后是商业
category.business
如果你想要孩子(寿司,披萨,中国......)那么
category.childrens
要查找所有类别,请在category.rb
中添加以下方法 def all_children
all = []
self.children.each do |category|
all << category
root_children = category.all_children.flatten
all << root_children unless root_children.empty?
end
return all.flatten
end
然后使用
@category.all_children
EDITED 查找餐厅类别和餐厅所有子类别的商家。
Business.where("category_id = ? OR category_id in (?)", category.id, category.all_children.map(&:id))
答案 2 :(得分:0)
你能做的事情不仅仅是:
Category.find_by_name("Restaurants").businesses
修改强>
没有意识到你想在餐馆的子类别中做生意,呃。
对于多层次的层次结构,您首先需要获取所有类别,然后遍历每个类别,查找业务,然后将它们连接在一起
class Company < ActiveRecord::Base
...
def all_children
all = []
self.children.each do |c|
all << c
root_cs = c.all_children.flatten
all << root_cs unless root_cs.empty?
end
return all.flatten
end
end
然后你可以打电话:
root_category = Category.find_by_name("Restaurants")
categories = root_category.all_children
businesses = categories.map{ |c| c.businesses }.flatten
那应该会给你一份商家清单。虽然这看起来不太好,但我觉得应该有更优化的方式。
希望无论如何它应该给你一些思考的食物。