我有以下几点:

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


在菜单中通过has_many:through。这将仅获得顶级菜单项,而不是更深层次的菜单项。我尝试将menu_id添加到menu_headers,但这迫使我放入commented_out行,这使我回到仅获取顶级标题的位置。有没有办法说出我所有的menu_header更深层次的内容,以便上面的内容起作用?

是否有解决此问题的方法?我非常迷恋acts_as_tree,因此使用awesome_nested_set之类的东西并不是真的。

谢谢

编辑-以下评论中的几个问题;我是在凌晨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进行更新时,将缓存的副本仅存储在菜单表中。

会调查Ancestry,但由于其他代码都依赖于此,因此不愿迁移到另一个gem。如果可以很快完成,也许可以,但这是一个相当复杂的对象,包含许多其他部分,并且act_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 |
+----+----------------------------------------------------+----------------+


谢谢

最佳答案

试试这个。

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

关于ruby-on-rails - actions_as_tree和has_many:不能很好地协同工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8296551/

10-13 06:38