2017-02-20 74 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 
相关问题