3

我有以下几点:acts_as_tree和的has_many:通过不工作得很好

class Menu < ActiveRecord::Base 
    has_many :menu_headers 
    # has_many :menu_headers, :conditions => {:parent_id => 0} - was trying 
    # to set parent_id to 0 for top level 
    has_many :menu_items, :through => :menu_headers 
end 

class MenuHeader < ActiveRecord::Base 
    belongs_to :menu 
    has_many :menu_items 
    acts_as_tree 
end 

class MenuItem < ActiveRecord::Base 
    #belongs_to :menu 
    has_one :menu, :through => :menu_header 
    belongs_to :menu_header 
end 

编辑#3 - 种子数据样本 这里是一个例子,如何将播(想同时获得mi_1和mi_2 )

m_1=Menu.create({:name => "Dinner Menu test", :location_id => 145}) 
c_1=m_1.menu_headers.create({:name => "White Wine"}) 
c_2=c_1.children.create({:name => "Sauvignon Blanc"}) 
mi_1=c_2.menu_items.create({:header => "SB menu item #1"}) 
mi_2=c_1.menu_items.create({:header => "SB menu item #2"}) 
m_1.menu_items # returns only mi_2; would like both mi_2 and mi_1 

结束编辑#3

的问题是,我不能做以下返回所有menu_items:

m=Menu.find(5) 
m.menu_items 

for has_many:through in Menu。这将仅获得顶层菜单项而不是更深层次的菜单项。我尝试将menu_id添加到menu_headers,但是这迫使我将其置于commental_out行,这让我回到只有顶级标题。有什么方法可以让我把menu_header的所有更深层次都展示给上述人员吗?

有没有解决这个或其他什么?我几乎卡住了acts_as_tree,所以使用类似awesome_nested_set的东西并不是真的在卡中。

thx

EDITS - 在下面的评论中的几个问题;我在凌晨4点

编辑#2
写这个我能够通过它来获取所有的孩子:

class MenuHeader < ActiveRecord::Base 
    ... 
    # only gets all children of the current menu_header_id 
    def all_children 
    all = [] 
    self.children.each do |menu_header| 
     all << menu_header 
     root_children = menu_header.all_children.flatten 
     all << root_children unless root_children.empty? 
    end 
    return all.flatten 
    end 

end 

我想能够调用all_children和主菜单项获得menu_items。也许将上面的内容与主菜单项上的调用集成在一起,然后在menu_item更新时只将菜单表中的缓存副本存储起来。

会考虑到祖先,但是由于其他代码依赖于此,所以不愿意移动到另一个宝石。如果可以快速完成,可能没问题,但这是一个相当复杂的对象,其中许多其他部分,acts_as_tree相当简单。

编辑#4 - 这里是样本数据:

menus 
+----+-------------+------------------+ 
| id | location_id | name    | 
+----+-------------+------------------+ 
| 1 |   145 | item cocktails | 
+----+-------------+------------------+ 

menu_headers        
+----+----------------------+-----------+---------+ 
| id | name     | parent_id | menu_id | 
+----+----------------------+-----------+---------+ 
| 1 | Wines By The Glass |   0 |  1 | 
| 2 | WHITE WINES   |   1 | NULL | 
| 3 | WHITE WINES child #1 |   2 | NULL | 
| 4 | WHITE WINES child #2 |   2 | NULL | 
| 5 | WHITE WINES child #3 |   2 | NULL | 
| 6 | RED WINES   |   0 |  1 | 
+----+----------------------+-----------+---------+ 

menu_items 
+----+----------------------------------------------------+----------------+ 
| id | header            | menu_header_id | 
+----+----------------------------------------------------+----------------+ 
| 1 | SAUVIGNON BLANC item #1       |    2 | 
| 2 | MONTEPULCIANO          |    6 | 
+----+----------------------------------------------------+----------------+ 

THX

+0

尚不完全清楚你想要什么,并获得。你想要'Menu.find(5).menu_items'返回5号菜单项(我期望它),或所有的菜单对象是5号的后代(我不希望它,开箱)?前者为 – Chowlett

+0

; Menu.find(5).menu_items应该返回菜单ID = 5的所有menu_items 5 – timpone

+0

嗯。如果将'MenuItem'改为'belongs_to:menu,:through =>:menu_headers',会怎样? – Chowlett

回答

0

更好的尝试。

class Menu < ActiveRecord::Base 
    has_many :menu_headers, :conditions => {:parent_id => 0} 
    has_many :menu_sub_headers, :class_name => 'MenuHeader' 
    has_many :menu_items, :through => :menu_sub_headers 
end 

class MenuHeader < ActiveRecord::Base 
    belongs_to :menu 
    has_many :menu_items 
    acts_as_tree 
end 

class MenuItem < ActiveRecord::Base 
    has_one :menu, :through => :menu_header 
    belongs_to :menu_header 
end 

这应该给:

m1=Menu.create(:name => "Dinner Menu test", :location_id => 145) 
c1=m1.menu_headers.create(:name => "White Wine") 
c2=c1.children.create(:name => "Sauvignon Blanc", :menu => m1) 
mi1=c2.menu_items.create(:header => "SB menu item #1") 
mi2=c1.menu_items.create(:header => "SB menu item #2") 
m_1.menu_items # should return mi1 and mi2 
m_1.menu_headers # should return just c1 
m_1.menu_sub_headers # should return c1 and c2 
+0

让我看看。 thx – timpone

+0

因此,它看起来像使用这两种策略 - 让acts_as_tree做它的事情,然后创建第二个关系来处理has_many:通过? – timpone

+0

非常。 'acts_as_tree'是相当偶然的;最重要的是你有两个'Menu'关系'MenuHeader' - 有一个条件可以缩小到顶层,而另一个选择所有的东西,所以':通过'工作。这是否为你工作? – Chowlett

0

你可以试试ancestry,在我看来它比acts_as_tree

+0

我有点卡住acts_as_tree,除非我能得到一个方法来相当快地转换它。让我看一看 - 是否会支持我想要做的事情? – timpone

+0

我想我用祖先看到的问题是我是否可以将它与has_many:through结合使用。例如,这看起来不太好https://github.com/stefankroes/ancestry/issues/49 – timpone