如何做 Elixir 混入

How to do Elixir mixins

我正在尝试创建一个用于身份验证登录的 mixins,因此它可以应用于我应该能够登录的模型。很像 Ruby.

中的 has_secure_password

Afaik 这是使用 use 语句完成的,该语句需要模块,并调用 __using__ 宏。所以我这样实现了我的mixin。

defmodule MyApp.SecurePassword do
  defmacro __using__(_options) do
    quote do
      import MyApp.SecurePassword
    end
  end

  defmacro authenticate(password) do
    # Lets return true, for testing purposes.
    true
  end
end

然后我在我的 "user" 模型中调用 use。

defmodule MyApp.Farm do
  use MyApp.Web, :model
  use MyApp.SecurePassword

  schema "farms" do
    field :name, :string
    field :email, :string
  #.....

在我的控制器中,我正在尝试使用该方法。

 def create(conn, %{"session" => session_params}) do
    user = Repo.get_by(Farm, email: session_params["email"])

    if user && user.authenticate(session_params["password"]) do
      conn = put_flash(conn, :success, "You were successfully logged in")
    else
      conn = put_flash(conn, :error, "Credentials didn't match")
    end

    redirect(conn, to: session_path(conn, :new))
 end

但是当我输入代码时,我在调用身份验证函数的那一行遇到了一个参数错误。

我的微距技巧比较弱,我做错了什么? :)

我想你想要的是调用传入用户和密码的authenticate函数:

def authenticate(user, password) do
  # auth logic
end

然后:

import MyApp.SecurePassword
# ...
if user && authenticate(user, session_params["password"]) do
# ...

目前似乎没有任何理由使用宏或 use,一个简单的 import 就可以了——你只需要在生成一些代码编译时和在这种情况下,您想要的一切似乎都会在运行时发生。