2016-10-06 39 views
1

假設我有一個User模型,其中has_manyPost如何預加載關聯並將其返回給ecto?

我拿來用戶:

user = Repo.get(User, 1) 

,現在我想獲得該用戶的所有帖子。我發現的唯一解決方案是:

posts = Repo.preload(user, :posts).posts 

但它很醜。那有沒有簡寫?

回答

4

您可以使用Ecto.assoc/2獲得查詢所有的職位,然後傳遞到Repo.all/1實際獲取它們:

iex(1)> user = Repo.get(User, 1) 
iex(2)> Ecto.assoc(user, :posts) 
#Ecto.Query<from p in MyApp.Post, where: p.user_id == ^1> 
iex(3)> Ecto.assoc(user, :posts) |> Repo.all 
[debug] QUERY OK source="posts" db=2.4ms 
SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "posts" AS p0 WHERE (p0."user_id" = $1) [1] 
... 
+0

有什麼速記'assoc'和'preload'之間的區別? – arpit

+0

'assoc'爲特定關聯構建查詢而不從db檢索數據,'preload'從數據庫中檢索數據進行關聯,包括嵌套關聯。 – Voldy

+0

請注意,'preload/2'在一個數據結構中返回父記錄(在這種情況下爲用戶)和關聯的記錄(帖子),而傳遞給'Repo.all'的'assoc/2'只返回相關記錄(帖子)。這意味着如果你需要父記錄,你可以單獨獲取它們(如上面的例子),但是如果你完全把它寫成管道語句,你將不會獲得這些數據。 – tomf

0
user = Repo.get(User, 1) |> preload(:posts) 

是對你的情況

0
user = Repo.get(User, 1) |> Repo.preload([:posts]) 
+0

儘管這段代碼可能會回答這個問題,但通常認爲添加對代碼的作用的解釋是很好的做法。這使得那些在這方面不熟悉的開發人員能夠理解代碼中發生了什麼,並幫助他們學習如何在未來自己解決問題。 –

相關問題