2016-05-31 58 views
3

雖然我經過查詢資料庫由this answer這樣的啓發:爲什麼我得到協議Enumerable沒有爲#Ecto.Query實現?

teams_users = Repo.all (from(t in Team, where: t.owner_id == ^user_id)) 
    |> Enum.each(&team_users/1) 


def team_users (team) do 
    %{id: id} = team 
    Repo.all (from(tu in TeamUser, where: tu.team_id == ^id)) 
end 

不過,我得到這個錯誤:

[error] GenServer #PID<0.450.0> terminating 
** (Protocol.UndefinedError) protocol Enumerable not implemented for #Ecto.Query<from t in App.Team, where: t.owner_id == ^1> 
    (elixir) lib/enum.ex:1: Enumerable.impl_for!/1 
    (elixir) lib/enum.ex:116: Enumerable.reduce/3 
    (elixir) lib/enum.ex:1477: Enum.reduce/3 
    (elixir) lib/enum.ex:609: Enum.each/2 
    (App) web/channels/user_channel.ex:93: App.UserChannel.handle_in/3 
    (phoenix) lib/phoenix/channel/server.ex:223: Phoenix.Channel.Server.handle_info/2 
    (stdlib) gen_server.erl:615: :gen_server.try_dispatch/4 
    (stdlib) gen_server.erl:681: :gen_server.handle_msg/5 
    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3 

什麼我試圖做的是讓所有的球隊,然後獲得每個團隊的用戶,那麼我希望所有的用戶都在一個陣列中。

我想念什麼?有什麼建議?有沒有更好的方法來實現這一目標?

回答

4

所以你在這裏有一個問題與此代碼:

teams_users = Repo.all (from(t in Team, where: t.owner_id == ^user_id)) 
|> Enum.each(&team_users/1) 

您應該刪除Repo.all(

之間

teams_users = Repo.all(from(t in Team, where: t.owner_id == ^user_id)) 
|> Enum.each(&team_users/1) 
的空間你也可以這樣寫:

teams_users = 
from(t in Team, where: t.owner_id == ^user_id) 
|> Repo.all() 
|> Enum.each(&team_users/1) 

但是,這樣做會引入n + 1個查詢。您將進行一次查詢以獲取您的團隊,然後再查詢另一個團隊用戶。你應該看看Repo.preload/2

teams_users = 
    from(t in Team, where: t.owner_id == ^user_id) 
    |> Repo.all() 
    |> Repo.preload(:team_users) 
+0

但是,我將如何定義模式Team中的關聯:team_users?我正在使用ecto 3.0-rc,並且我已經有了多對多的表格,但是我沒有在我的團隊,用戶模式中添加任何關聯.. – simo

+0

https://hexdocs.pm/ecto/Ecto.Schema.html #has_many/3和https://hexdocs.pm/ecto/Ecto.Schema.html#belongs_to/3應該可以幫助你。 – Gazler

+0

我不能添加'belongs_to'給用戶,因爲它沒有'table_id',我正在使用另一個表'team_user'來鏈接擁有'user_id,team_id'的團隊和用戶如何定義多對多關聯? – simo

相關問題