2017-02-20 72 views
0

說我有以下外生型號:如何爲每個記錄預加載一個關聯?

  • ForumCategoryhas_many :forums
  • Forumbelongs_to :forum_categoryhas_many :forum_topics
  • ForumTopicbelongs_to :forum

且說我要加載的ForumCategory所有條目與所有關聯的Forum條目已預裝並且最新的ForumTopic對於這些:

ForumCategory - >Forum - >ForumTopic

在論壇類預加載論壇很簡單:

ForumCategory 
|> preload(:forums) 

現在,我們也想預裝最新的論壇主題,但我們只希望爲每個論壇預先加載單個最新主題,所以我們不會從數據庫中加載論壇主題的全部列表(其中會有很多)

forum_topics_query = ForumTopic 
        |> order_by([desc: :inserted_at]) 
        |> limit(1) 
ForumCategory 
|> preload([forums: [forum_topics: ^forum_topics_query]]) 
|> Repo.all 

這看起來似乎乍一看,但很快顯而易見,該查詢只返回一個論壇主題,而不是每個論壇一個,而是一個論壇主題,這也從實際的SQL查詢中很清楚執行:

SELECT f0."id", f0."title", f0."body", f0."pinned", f0."forum_replies_count", f0."deleted_at", f0."inserted_at", f0."updated_at", f0."forum_id", f0."user_id", f0."forum_id" 
FROM "forum_topics" AS f0 WHERE (f0."forum_id" = ANY($1)) 
ORDER BY f0."forum_id", f0."inserted_at" DESC 
LIMIT 1 

所以我的問題是,如何讓我外生預緊力不只是一個單一的紀錄在總而是在每個論壇類別預裝每一個論壇?

回答

0

我結束了該解決方案使用的連接和窗口功能組合:

defmodule MyApp.ForumTopic do 
    def latest_over_forum(per \\ 1) do 
    from outer in __MODULE__, 
     join: inner in fragment(""" 
     SELECT *, row_number() OVER (
      PARTITION BY forum_id 
      ORDER BY inserted_at DESC 
     ) FROM forum_topics 
     """), 
     where: inner.row_number <= ^per and inner.id == outer.id 
    end 
end 

forum_topics_query = ForumTopic |> ForumTopic.latest_over_forum 
ForumCategory 
|> preload([forums: [forum_topics: ^forum_topics_query]]) 
|> Repo.all 
相關問題