首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ecto模型参数未验证?

ecto模型参数未验证?
EN

Stack Overflow用户
提问于 2016-06-20 19:01:20
回答 1查看 192关注 0票数 1

可能是我遗漏了什么,但它觉得这应该是一个无效的记录:

代码语言:javascript
复制
pry(1)> project_params
%{"name" => ""}
pry(2)> changeset
%Ecto.Changeset{action: nil, changes: %{name: ""}, constraints: [], errors: [],
 filters: %{},
 model: %Elix.Project{__meta__: #Ecto.Schema.Metadata<:built>, id: nil,
  inserted_at: nil, name: nil, updated_at: nil,
  user: #Ecto.Association.NotLoaded<association :user is not loaded>,
  user_id: 2}, optional: [], opts: [], params: %{"name" => ""}, prepare: [],
 repo: nil, required: [:name, :user_id],
 types: %{id: :id, inserted_at: Ecto.DateTime, name: :string,
   updated_at: Ecto.DateTime, user_id: :id}, valid?: true, validations: []}
pry(3)> changeset.valid?
true

下面是我对模型的定义:

项目

代码语言:javascript
复制
defmodule Elix.Project do
  use Elix.Web, :model

  schema "projects" do
    field :name, :string
    belongs_to :user, Elix.User

    timestamps
  end

  @required_fields ~w(name user_id)
  @optional_fields ~w()

  @doc """
  Creates a changeset based on the `model` and `params`.

  If no params are provided, an invalid changeset is returned
  with no validation performed.
  """
  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

用户

代码语言:javascript
复制
defmodule Elix.User do
  use Elix.Web, :model

  schema "users" do
    field :email, :string
    field :password, :string, virtual: true
    field :crypted_password, :string
    has_many :projects, Elix.Project

    timestamps
  end

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

  @doc """
  Creates a changeset based on the `model` and `params`.

  If no params are provided, an invalid changeset is returned
  with no validation performed.
  """
  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
    |> unique_constraint(:email)
    |> validate_format(:email, ~r/@/)
    |> validate_length(:password, min: 5)
  end
end

这是控制器创建操作的代码:

代码语言:javascript
复制
def create(conn, %{"project" => project_params}) do
    changeset =
      Ecto.build_assoc(conn.assigns.current_user, :projects) |>
      Project.changeset(project_params)
IEx.pry
    case Repo.insert(changeset) do
      {:ok, project} ->
        conn
        |> put_flash(:info, "Project #{project.name} created succesfully")
        |> redirect(to: project_path(conn, :index))
      {:error, changeset} ->
        render(conn, "new.html", project: changeset)
    end
  end

我提交表单时没有故意输入任何内容,这样我就可以测试表单显示错误。我在这里错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-20 19:27:53

只有当changeset.valid?的值为nil时,name才会是nil。因为在您的情况下,name的值是空字符串,所以变更集将是有效的。

处理以值形式传递空字符串的表单的最佳位置是在控制器中添加scrub_params插件,如下所示:

plug :scrub_params, "project" when action in [:create, :update]

有关文档的更多信息,请查看scrub_params

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37929931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档