Repo在Phoenix控制器中注入的位置是什么?

时间:2018-01-12 13:41:52

标签: elixir phoenix-framework

这几乎是一个新手问题,所以如果答案显而易见,我会道歉,但我现在已经有一段时间无法解决这个问题了。

我跟随实用程序员(this)的凤凰书。通过查看相应的github repo,我相信是为1.1版编写的。到目前为止,我已经能够通过查看升级说明等来使其工作。但是当我到达"实施登录和注销"我遇到了错误auth.ex

我一直在寻找代码,试图找出Repo应该从哪里提供?错误本身在session_controller.ex中调用,但缺少的模块作为参数从session_controller.ex传递,因此我已将两者都包括在内。

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

auth.ex

def login_by_username_and_pass(conn, username, given_pass, opts) do repo = Keyword.fetch!(opts, :repo) user = repo.get_by(Rumbl.User, username: username) cond do user && checkpw(given_pass, user.password_hash) -> {:ok, login(conn, user)} user -> {:error, :unauthorized, conn} true -> dummy_checkpw() {:error, :not_cound, conn} end end Link to file in github

call

我将我的代码与似乎Link to file in github的代码进行了比较,我发现的唯一区别是它似乎是凤凰版1.1.1而不是1.3。

Repo来自哪里,为何在这里无法使用?我注意到它auth.ex内的$arrayExemple= [ ['value1', 'value2'], ['value1', 'value2'], ['value1', 'value2'], ['value1', 'value2'] ]; 中可用,但我认为这可能是因为当它包含在浏览器管道中时,这是标准的插件功能。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

您已在Rumbl.Repo拥有您的回购phxtutorial/lib/rumbl/repo.ex。问题是您的SessionController不知道您指的是哪个Repo,如果您没有别名,或者使用完整的模块名称。

您需要做的是将其替换为SessionController,如下所示:

defmodule RumblWeb.SessionController do
  use RumblWeb, :controller
  alias Rumbl.Router.Helpers
  alias Rumbl.Repo # This is the new alias

  ...
end

现在,您的SessionController知道您所指的repo: RepoRumble.Repo

答案 1 :(得分:1)

模块可以通过web.ex文件全局导入或别名为控制器,路由器,视图等。在您的项目中有一个lib/rumbl_web.ex正在执行导入和别名。

您可以在此处添加别名,并且Repo将在所有控制器中可用。就个人而言,我不会在控制器中提供Repo - 他们不需要了解Ecto。我会在每个上下文模块中包含Repo。这是更好的separation of concerns

除非单个上下文功能需要在多个repos上运行,否则我认为没有理由将控制器注入到该函数中。

如果你想变得非常花哨,你可以在rumbl_web.ex中为上下文模块定义另一个函数并添加到每个函数中:

use RumblWeb, :context

就个人而言,我只是在每个上下文模块中使用别名。