【问题标题】:Elixir/Phoenix - trouble updating belongs_to association after it has been setElixir/Phoenix - 设置后更新 belongs_to 关联时遇到问题
【发布时间】:2023-03-29 23:27:01
【问题描述】:

我有一个用户可以属于某个组的应用。用户和组可以单独创建,用户可以稍后添加到组中。

第一次将用户添加到组时,以下代码可以正常工作:

用户模型

use Ecto.Schema
import Ecto.Changeset

schema "users" do
  field :email, :string
  field :description, :string
  field :deleted, :boolean, default: false
  belongs_to :group, Admin.Group, foreign_key: :group_id, on_replace: :update

  timestamps()
end

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:code, :user_email, :description, :created_at, :deleted])
  |> validate_required([:code, :user_email, :created_at,])
end

用户控制器

def update(conn, %{"id" => id, "data" => data = %{"type" => "users", "attributes" => _user_params, "relationships" => relationships}}) do
  user = Repo.get!(User, id) |> Repo.preload :group
  group = Repo.get_by!(Group, id: data["relationships"]["group"]["data"]["id"])
  changeset = User.changeset(user, Params.to_attributes(data)) |> Ecto.Changeset.put_assoc(:group, group)
  case Repo.update(changeset) do
    {:ok, user} ->
      render(conn, "show.json-api", data: user)
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(:errors, data: changeset)
  end
end

上面的数据属性是这样的:

%{"attributes" => %{"description" => nil, "inserted_at" => "2017-12-01T14:20:58.423Z",
    "updated_at" => "2017-12-11T10:36:24.073Z",
    "email" => "test@gmail.com"}, "id" => "292",
  "relationships" => %{"group" => %{"data" => %{"id" => "1",
        "type" => "groups"}}}, "type" => "users"}

问题是,如果我尝试更改该用户所属的组,更新函数会返回200 OK,但组不会更改。

检查数据变量的输出显示请求有效负载中的组ID不同。

%{"attributes" => %{"description" => nil, "inserted_at" => "2017-12-01T14:20:58.423Z",
    "updated_at" => "2017-12-11T10:36:24.073Z",
    "email" => "test@gmail.com"}, "id" => "292",
  "relationships" => %{"group" => %{"data" => %{"id" => "2",
        "type" => "groups"}}}, "type" => "users"}

为什么变更集不能识别更新的组 ID?

【问题讨论】:

  • 在调用更新路由时记录到控制台的查询是什么?
  • [debug] Processing with Server.Admin.UserController.update/2 Parameters: %{"data" => %{"attributes" => %{"description" => nil, "inserted_at" => "2017-12-01T14:20:58.423Z", "updated_at" => "2017-12-11T10:36:24.073Z", "email" => "test@gmail.com"}, "id" => "292", "relationships" => %{"group" => %{"data" => %{"id" => "2", "type" => "groups"}}}, "type" => "users"}, "id" => "292"} Pipelines: [:admin_auth]
  • 我指的是运行Repo.update时的SQL查询。
  • 这是第一次更新用户时的更新查询` [debug] QUERY OK db=1.0ms UPDATE "users" SET "group_id" = $1, "updated_at" = $2 WHERE "id " = $3 [2, {{2017, 12, 11}, {14, 14, 12, 84337}}, 288]` 以后尝试更改组时根本不会发生这种情况。
  • 确定。如果我在控制器中记录变更集,它会返回 #Ecto.Changeset<action: nil, changes: %{}, errors: [], data: Admin.License<>, valid?: true>

标签: elixir phoenix-framework ecto


【解决方案1】:

我在模型中使用了不正确的 on_replace 值。它必须是 nilify 而不是 update

belongs_to :group, Admin.Group, foreign_key: :group_id, on_replace: :nilify

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多