【问题标题】:Why I get protocol Enumerable not implemented for #Ecto.Query?为什么我没有为#Ecto.Query 实现协议 Enumerable?
【发布时间】:2016-09-29 14:29:31
【问题描述】:

虽然我将查询传递给受this answer 启发的存储库,如下所示:

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

我要做的是获取所有团队,然后获取每个团队的用户,然后我希望将所有用户放在一个数组中。

我错过了什么吗?有什么建议吗?有没有更好的方法来实现这一点?

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    所以你对这段代码有疑问:

    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)
    

    【讨论】:

    • 但是,我将如何在模式 Team 中定义关联 :team_users?我正在使用 ecto 3.0-rc,我已经有一个多对多表,但我没有在我的团队、用户模式中添加任何关联..
    • 我无法将belongs_to 添加到用户,因为它没有table_id,我正在使用另一个表team_user 来链接具有user_id, team_id 的团队和用户我将如何定义许多许多协会?
    • 在我链接的文档中,有一个通过关联的例子。
    • 如果您使用的是 Ecto 2,请查看 stackoverflow.com/questions/35529720/…
    【解决方案2】:

    您将查询宏直接传送到 Enum.each,而不是使用 Repo.all 解析查询并将其发送到 Enum。

    【讨论】:

      猜你喜欢
      • 2016-09-17
      • 2017-07-01
      • 2017-11-26
      • 2015-09-03
      • 1970-01-01
      • 2020-05-18
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多