2014-10-28 94 views
0

我試圖抓住的一個工作流程工具,我正在做活動任務列表,結構類似這樣的數據:返回嵌套結果的查詢使用Rails的ActiveRecord

  • 用戶
    • 的has_many項目
      • 的has_many子項目
        • 的has_many任務
          • 的has_manyŤ imeLogs

活動的任務被定義爲與不具有 '已完成' 時間戳TimeLog任何任務。

我試圖讓主頁面顯示這個完整的結構,但只顯示在某個級別有活動任務的父結構。任何在其下沒有活動任務的用戶/項目/子項目都不應該被查詢返回。

到目前爲止,我已經嘗試:在所有四個表,產生重複的行

  • 聯接
  • 一個WHERE EXISTS語句,該語句只返回相關的用戶,但不維護WHERE子句當我試圖訪問它的孩子

有沒有一種方法來實現這一點,而無需手動剔除Ruby中的數據?

+0

您可以在連接查詢的末尾添加'.uniq'。然後ActiveRecord將查詢沒有重複。 – 2014-10-28 14:00:21

+0

這適用於頂級用戶,但是當我抓取用戶的子項目時,它只抓取所有項目。通過子節點執行'where'子句似乎很麻煩,所以我正在尋找一種方法來一次抓住它,也許將ActiveRecord查詢轉換爲嵌套的Hash? – 2014-10-28 14:26:37

回答

1

由於問題的嵌套級別,它可能相當複雜。據我所知,你想省略沒有任何活動任務的用戶|項目|子項目。有沒有簡單的SQL,將讓你實現,通過:

users.each do |user| 
    user.active_projects.each do |project| 
    ... 
    end 
end 

相反,我會查詢任務的第一個,即@tasks = Task.includes(:subproject => [:project => :user]).where("status NOT IN ('completed')")。然後你未完的任務,現在你需要做的是重新排序取的數據,我的意思是:

@tasks = @tasks 
.group_by {|t| t.subproject.project.user } 
.reduce({}) do |sum, (user, tasks)| 
    sum[user] ||= {} 
    tasks.each do |task| 
    sum[user][task.subproject.project] ||= {} 
    sum[user][task.subproject.project][task.subproject] ||= [] 
    sum[user][task.subproject.project][task.subproject] << task 
    end 
    sum 
end 

我沒有測試過這一點,但是這是想法。

+0

Bleh,所以最好的方法是手動構建樹。我擔心會是這樣。感謝代碼示例。 – 2014-10-28 14:55:48

0

你可以基於該activerecord queries documents試試這個:

user.projects.joins(subprojects: { tasks: [{ time_logs: { timestamp: 'completed'} }] }) 

我不能測試,但給它一個鏡頭。

+0

不幸的是,那是我的第一個想法,但如果用戶有多個活動任務,連接將返回重複行,正如我在評論中提到的那樣,'.uniq'不會將'where'子句應用於子關係。 – 2014-10-28 14:54:00