Ecto Changeset - 如果没有给出输入,则不进行关联

问题描述 投票:1回答:1

我有一个用户架构

  schema "users" do
    field :name, :string
    field :username, :string
    has_one :user_role, UserRole
  end

  def changeset(%User{} = user, attrs) do
    user
    |> cast(attrs, [:name, :username])
    |> validate_required([:name, :username])
    |> unique_constraint(:username)
  end

和UserRole架构

  schema "userroles" do
    field :is_admin, :boolean, default: false
    belongs_to :user, User
  end

  def changeset(%UserRole{} = user_role, attrs) do
    user_role
    |> cast(attrs, [:is_admin, :user_id])
    |> validate_required([:is_admin])
  end

它们都在“帐户”的相同上下文中,我在其中转换关联。

      #accounts.ex      
      def create_user(attrs \\ %{}) do
        %User{}
        |> User.changeset(attrs)
        |> Ecto.Changeset.cast_assoc(:user_role, required: true)
        |> Repo.insert()
      end

这是UserController的新增功能和创建:

  def new(conn, _params) do
    changeset = Accounts.change_user(%User{})
    render(conn, "new.html", changeset: changeset)
  end

  def create(conn, %{"user" => user_params}) do
    case Accounts.create_user(user_params) do
      {:ok, user} ->
        conn
        |> put_flash(:info, "User created successfully.")
        |> redirect(to: user_path(conn, :show, user))
      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

我有一个用户和UserRole的嵌套表单。如果我输入所有数据,一切都按预期工作。现在,我想隐藏UserRole的输入,因为我不希望用户将自己设置为“is_admin”(但如果您是管理员,则应该能够创建其他管理员帐户)。因此,如果您是非管理员用户,则不再有UserRole的输入。我的期望是这样的

  1. 如果没有输入或者,将插入UserRole架构的默认值
  2. UserRole的变更​​集中的验证将说没有输入,但它是必需的。

发生的事情是:用户已创建,但关联的user_role为“nil”。我不明白为什么会这样。任何人都可以向我解释一下吗?

我的解决方案是:不是给用户一个布尔值的复选框:is_admin,我发送一个隐藏的输入,将其设置为false,但它似乎不是好方法。

elixir phoenix-framework
1个回答
1
投票

你可以随时使用

在这种情况下Map.put_new(map, key, value)

之前

case Accounts.create_user(user_params) do

使用params = Map.put_new(user_params, :user_role, "anything")

这将做的是,如果它在地图中找到:user_role,它将使用相同的,如果它没有找到任何东西,它将使用你指定的值。

它需要user_role的值,因为有一个与之相关的关联。虽然我觉得它应该是has_many协会,但你的代码显示其has_one,所以对于每个user条目应该有user_role相关联。

如果要使用has_manybelongs_to应该在user模式中,而has_manyuser_role模式中

© www.soinside.com 2019 - 2024. All rights reserved.