2011-08-05 55 views
3

要求:

我正在構建任務列表應用程序,並希望任務能夠具有子任務。
我也希望任務能夠在樹多的地方一下子存在,例如,如果我有2項任務:Rails3:避免選擇n + 1與祖先寶石?

  1. 構建狗窩
  2. 放上新的柵欄

如果我計劃用與圍欄相同的材料建造狗舍,那麼這兩項任務都會有一個「購買圍欄」的子任務。

我的問題的實施(反饋歡迎):

我有2種型號:

  • 節點(has_ancestry和belongs_to的:任務)
  • 任務(的has_many:節點)

這意味着樹(允許我有子任務)不會自行存儲任務,只是對任務對象的引用。

在這裏使用的示例導軌控制檯:

t1 = Task.create :name => "Build dog kennel" 
n1 = Node.create :task => t1 

t2 = Task.create :name => "Put up new fence" 
n2 = Node.create :task => t2 

t3 = Task.create :name => "Buy fence palings" 
n11 = Node.create :task => t3, :parent => n1 
n21 = Node.create :task => t3, :parent => n2 

t4 = Task.create :name => "Construct the fence" 
n22 = Node.create :task => t4, :parent => n2 

n2.children.each { |c| puts c.task.name } 

最後一行給出了下面的輸出,指示選擇的n + 1:

Node Load (0.2ms) SELECT "nodes".* FROM "nodes" WHERE "nodes"."ancestry" = '12' 
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = 11 LIMIT 1 
Buy fence palings 
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = 10 LIMIT 1 
Put up new fence 

幫助?

我對Ruby on Rails和ActiveRecord相當陌生,但我認爲我需要做的就是根據nodes.task_id外鍵將節點表與任務表連接起來,但我已通過Ancestry documentation並找不到有用的東西。

未來,我打算通過外鍵(如作者,相關注釋等)從任務對象獲取更多信息,並且通過此實現,一個頁面加載可能觸發相當多的選擇查詢:(

任何人都可以給我就如何做到這一點建議嗎?
有沒有辦法迫使急於加載?(但願幫忙嗎?)
我接受反饋,如果你有更好的想法如何做到這一點。

在此先感謝!

回答

7

所以在玩了一段時間之後,我終於找到了一種方法來做到這一點。

而是這行:

n2.children.each { |c| puts c.task.name } 

導致此:

Node Load (0.2ms) SELECT "nodes".* FROM "nodes" WHERE "nodes"."ancestry" = '27' 
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = 23 LIMIT 1 
Buy fence palings 
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = 24 LIMIT 1 
Construct the fence 

我用這條線:

n2.children.find(:all, :include => :task).each { |c| puts c.task.name } 

這就造成了這一點:

Node Load (0.2ms) SELECT "nodes".* FROM "nodes" WHERE "nodes"."ancestry" = '27' 
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" IN (23, 24) 
Buy fence palings 
Construct the fence 

這應該只執行2個查詢,不管大小和結果集將包括任務!
我知道這可能是基本的東西,但它可能有點混亂像我自己的新來者,因爲section of the rails guides that refers to eager loading只顯示類方法includes()