You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phoenix控制器中Repo的注入位置及未找到问题排查

解决Phoenix 1.3中Repo.get_by/2 is undefined的问题

别担心,新手遇到版本适配的问题太正常了,这绝对不是你的问题!你遇到的核心原因是Phoenix 1.1和1.3之间的架构变化,尤其是Repo模块的命名方式。

问题根源

在Phoenix 1.1中,Repo是全局可用的(默认被导入到所有controller和view中),但从Phoenix 1.3开始,官方引入了Context架构,Repo模块被放在了项目的命名空间下,比如你的项目是Rumbl,那么Repo的完整模块名是Rumbl.Repo,而不是全局的Repo。

你在session_controller.ex中传入的Repo其实是未定义的,因为1.3不再全局导入这个模块了。

解决方案

方案1:直接使用完整的Repo模块名

修改session_controller.ex中的调用,把Repo替换成Rumbl.Repo:

def create(conn, %{"session" => %{"username" => user, "password" => pass}}) do
  case Rumbl.Auth.login_by_username_and_pass(conn, user, pass, repo: Rumbl.Repo) do
    {:ok, conn} -> ...
    {:error, _reason, conn} -> ...
  end
end

方案2:全局导入Repo到所有Controller

如果你想保持和1.1类似的写法(不用每次写全名),可以修改web/web.ex文件,找到controller的定义部分,添加import Rumbl.Repo:

def controller do
  quote do
    use Phoenix.Controller, formats: [:html, :json], layouts: [html: RumblWeb.LayoutView]

    import Plug.Conn
    import RumblWeb.Gettext
    alias Rumbl.Router.Helpers, as: Routes
    # 添加这行
    import Rumbl.Repo
  end
end

这样所有controller都能直接使用Repo,不用写全名了。

验证auth.ex中的Repo使用

你提到auth.ex的call函数能正常使用Repo,大概率是因为那里已经正确导入了Rumbl.Repo,或者使用了完整模块名。如果后续遇到问题,也可以检查auth.ex中是否有类似alias Rumbl.Repo或者直接用Rumbl.Repo的代码。

补充说明

Phoenix 1.3的Context架构是为了更好地组织代码,把相关的业务逻辑和数据访问封装在Context中,而不是直接在controller里操作Repo。你后续跟着《Programming Phoenix》学习时,可能需要把书中1.1的代码适配到1.3的Context模式,但当前先解决Repo的问题就能继续推进登录功能啦。

内容的提问来源于stack exchange,提问作者Robin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:55:17