Reputation: 545
I have an app in which a user can belong to a group. Users and groups can be created separately, and a user can be added to a group later on.
The code below works fine the first time a user is added to a group:
User Model
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
User Controller
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
The data attribute for the above looks like this:
%{"attributes" => %{"description" => nil, "inserted_at" => "2017-12-01T14:20:58.423Z",
"updated_at" => "2017-12-11T10:36:24.073Z",
"email" => "[email protected]"}, "id" => "292",
"relationships" => %{"group" => %{"data" => %{"id" => "1",
"type" => "groups"}}}, "type" => "users"}
The problem is that if I try and change the group that that user belongs to, the update function returns 200 OK
, but the group does not change.
Checking the output of the data variable shows that the group id is different in the request payload.
%{"attributes" => %{"description" => nil, "inserted_at" => "2017-12-01T14:20:58.423Z",
"updated_at" => "2017-12-11T10:36:24.073Z",
"email" => "[email protected]"}, "id" => "292",
"relationships" => %{"group" => %{"data" => %{"id" => "2",
"type" => "groups"}}}, "type" => "users"}
Why would the changeset not recognize the updated group id?
Upvotes: 0
Views: 1050
Reputation: 545
I was using the incorrect value for on_replace
in the model. It needed to be nilify
instead of update
.
belongs_to :group, Admin.Group, foreign_key: :group_id, on_replace: :nilify
Upvotes: 0