Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何使用ecto和phoenix v1.3创建用户_Elixir_Phoenix Framework_Ecto - Fatal编程技术网

Elixir 如何使用ecto和phoenix v1.3创建用户

Elixir 如何使用ecto和phoenix v1.3创建用户,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我有一个phoenix/phx v1.3项目,我一直在工作,在尝试使用iex会话创建用户时遇到了一个问题。据我所知,我写的代码应该可以工作,因为应用程序可以编译 我运行下面的生成器为用户帐户设置schema mix phx.gen.json Accounts User users email:string encrypted_password:string username:string 然后,我学习了一些教程,介绍如何通过修改 /lib/kegcopr_api/accounts/user.e

我有一个phoenix/phx v1.3项目,我一直在工作,在尝试使用
iex
会话创建用户时遇到了一个问题。据我所知,我写的代码应该可以工作,因为应用程序可以编译

我运行下面的生成器为用户帐户设置
schema

mix phx.gen.json Accounts User users email:string encrypted_password:string username:string
然后,我学习了一些教程,介绍如何通过修改

/lib/kegcopr_api/accounts/user.ex
user.ex

defmodule KegCopRAPI.Accounts.User do
  use Ecto.Schema
  # import Ecto
  import Ecto.Changeset
  # import Ecto.Query

  schema "accounts_users" do
    field :email, :string
    field :encrypted_password, :string
    field :username, :string
    field :password, :string, virtual: true

    timestamps()
  end

  @required_fields ~w(email username)
  @optional_fields ~w()

  def changeset(struct, params \\ :empty) do
    struct
    |> cast(params, @required_fields, @optional_fields)
    |> validate_required(@required_fields, @optional_fields)
    # |> cast(params, [:email, :encrypted_password, :username])
    # |> validate_required([:email, :encrypted_password, :username])
    |> validate_format(:email, ~r/@/)
    |> validate_length(:username, min: 1, max: 20)
    |> update_change(:email, &String.downcase/1)
    |> unique_constraint(:email)
    |> update_change(:username, &String.downcase/1)
    |> unique_constraint(:username)
  end

  def registration_changeset(struct, params) do
    struct
    |> changeset(params)
    |> cast(params, ~w(password), [])
    |> validate_required(~w(password), [])
    |> validate_length(:password, min: 6, max: 100) |> put_encrypted_pw
  end

  defp put_encrypted_pw(changeset) do
    case changeset do
      %Ecto.Changeset{valid?: true, changes: %{password: pass}} -> put_change(changeset, :encrypted_password, Comeonin.Bcrypt.hashpwsalt(pass))
    _ ->
      changeset
    end
  end
end
然后,我运行
iex-S mix
启动应用程序的交互式elixir会话,并尝试使用以下命令将用户插入数据库

changeset = KegCopRAPI.Accounts.User.registration_changeset(%KegCopRAPI.Accounts.User{}, %{email: "first@example.com", username: "first", password: "password"})
但是,上面提到的命令给了我以下错误

warning: `Ecto.Changeset.cast/4` is deprecated, please use `cast/3` + `validate_required/3` instead
    (kegcopr_api) lib/kegcopr_api/accounts/user.ex:21: KegCopRAPI.Accounts.User.changeset/2
    (kegcopr_api) lib/kegcopr_api/accounts/user.ex:35: KegCopRAPI.Accounts.User.registration_changeset/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:438: :erl_eval.expr/5
    (elixir) src/elixir.erl:224: :elixir.erl_eval/3
    (elixir) src/elixir.erl:212: :elixir.eval_forms/4
    (iex) lib/iex/evaluator.ex:182: IEx.Evaluator.handle_eval/6
    (iex) lib/iex/evaluator.ex:175: IEx.Evaluator.do_eval/4
    (iex) lib/iex/evaluator.ex:155: IEx.Evaluator.eval/4
    (iex) lib/iex/evaluator.ex:61: IEx.Evaluator.loop/3
    (iex) lib/iex/evaluator.ex:21: IEx.Evaluator.init/4
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

** (ArgumentError) unknown field "email" for changeset on %KegCopRAPI.Accounts.User{__meta__: #Ecto.Schema.Metadata<:built, "accounts_users">, email: nil, encrypted_password: nil, id: nil, inserted_at: nil, password: nil, updated_at: nil, username: nil}
           (ecto) lib/ecto/changeset.ex:1318: Ecto.Changeset.ensure_field_exists!/2
           (ecto) lib/ecto/changeset.ex:1305: anonymous fn/5 in Ecto.Changeset.validate_required/3
         (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
           (ecto) lib/ecto/changeset.ex:1304: Ecto.Changeset.validate_required/3
    (kegcopr_api) lib/kegcopr_api/accounts/user.ex:22: KegCopRAPI.Accounts.User.changeset/2
    (kegcopr_api) lib/kegcopr_api/accounts/user.ex:35: KegCopRAPI.Accounts.User.registration_changeset/2
警告:`exto.Changeset.cast/4`已被弃用,请改用`cast/3`+`validate\u required/3`
(KegCopRAPI)lib/KegCopRAPI/accounts/user.ex:21:KegCopRAPI.accounts.user.changeset/2
(KegCopRAPI)lib/KegCopRAPI/accounts/user.ex:35:KegCopRAPI.accounts.user.registration\u changeset/2
(stdlib)erl_eval.erl:670::erl_eval.do_apply/6
(stdlib)erl_eval.erl:438::erl_eval.expr/5
(elixir)src/elixir.erl:224::elixir.erl_eval/3
(elixir)src/elixir.erl:212::elixir.eval_表单/4
(iex)lib/iex/evaluator.ex:182:iex.evaluator.handle_eval/6
(iex)lib/iex/evaluator.ex:175:iex.evaluator.do_eval/4
(iex)lib/iex/evaluator.ex:155:iex.evaluator.eval/4
(iex)lib/iex/evaluator.ex:61:iex.evaluator.loop/3
(iex)lib/iex/evaluator.ex:21:iex.evaluator.init/4
(stdlib)proc_lib.erl:247::proc_lib.init_p_do_apply/3
**(ArgumentError)在%KegCopRAPI.Accounts.User{uuuuu meta_uuu:#exto.Schema.Metadata上的变更集的未知字段“email”,电子邮件:nil,加密的密码:nil,id:nil,插入的密码:nil,密码:nil,更新的密码:nil,用户名:nil}
(exto)lib/exto/changeset.ex:1318:exto.changeset.sure_字段_存在/2.
(exto)lib/exto/changeset.ex:1305:exto.changeset.validate_required/3中的匿名fn/5
(elixir)lib/enum.ex:1755:enum。“-reduce/3-lists^foldl/2-0-”/3
(exto)lib/exto/changeset.ex:1304:exto.changeset.validate_required/3
(KegCopRAPI)lib/KegCopRAPI/accounts/user.ex:22:KegCopRAPI.accounts.user.changeset/2
(KegCopRAPI)lib/KegCopRAPI/accounts/user.ex:35:KegCopRAPI.accounts.user.registration\u changeset/2

任何关于如何创建用户的帮助都将不胜感激。目前,我不确定错误是在我输入的iex变更集命令中还是在
user.ex
文件中。

您正在将字符串列表传递给
验证所需的
,但它必须是原子列表<代码>强制转换可以选择其中一种。因此,将所有的
~w(…)
更改为
~w(…)a
,它应该可以工作。我还将删除不推荐使用的API

  @required_fields ~w(email username)a
  @all_fields ~w()a ++ @required_fields

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @all_fields)
    |> validate_required(@required_fields)
    # |> cast(params, [:email, :encrypted_password, :username])
    # |> validate_required([:email, :encrypted_password, :username])
    |> validate_format(:email, ~r/@/)
    |> validate_length(:username, min: 1, max: 20)
    |> update_change(:email, &String.downcase/1)
    |> unique_constraint(:email)
    |> update_change(:username, &String.downcase/1)
    |> unique_constraint(:username)
  end

  def registration_changeset(struct, params) do
    struct
    |> changeset(params)
    |> cast(params, ~w(password))
    |> validate_required(~w(password)a)
    |> validate_length(:password, min: 6, max: 100) 
    |> put_encrypted_pw
  end

您正在将字符串列表传递给
validate\u required
,但它必须是原子列表<代码>强制转换可以选择其中一种。因此,将所有的
~w(…)
更改为
~w(…)a
,它应该可以工作。我还将删除不推荐使用的API

  @required_fields ~w(email username)a
  @all_fields ~w()a ++ @required_fields

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @all_fields)
    |> validate_required(@required_fields)
    # |> cast(params, [:email, :encrypted_password, :username])
    # |> validate_required([:email, :encrypted_password, :username])
    |> validate_format(:email, ~r/@/)
    |> validate_length(:username, min: 1, max: 20)
    |> update_change(:email, &String.downcase/1)
    |> unique_constraint(:email)
    |> update_change(:username, &String.downcase/1)
    |> unique_constraint(:username)
  end

  def registration_changeset(struct, params) do
    struct
    |> changeset(params)
    |> cast(params, ~w(password))
    |> validate_required(~w(password)a)
    |> validate_length(:password, min: 6, max: 100) 
    |> put_encrypted_pw
  end

尝试将字段列表作为原子列表发送:
~w(密码)
->
~w(密码)a
。尝试将字段列表作为原子列表发送:
~w(密码)
->
~w(密码)a