"I have recently generated authorization using phx.gen
and attempted to add an additional field to the table. Subsequently, I implemented a method to update this new field. Then I updated the registration form and added a new form to the settings page. Currently, all functionalities are working as expected, except for the part that allows updating the name.
When i submit form “name_form” i don’t get any errors, but when i look up the database data doesn’t seem to change, i tried using IO.inspect()
(probably) everywhere and everything still seems fine.
Form:
<div>
<.simple_form
for={@name_form}
id="name_form"
phx-submit="update_name"
phx-change="validate_name"
>
<.input field={@name_form[:name]} type="text" label="Username" autocomplete="off" required />
<:actions>
<.button phx-disable-with="Changing...">Change username</.button>
</:actions>
</.simple_form>
</div>
I have two event handlers, one for validation and the other for updating:
def handle_event("validate_name", %{"user" => user_params}, socket) do
name_form =
socket.assigns.current_user
|> Accounts.change_user_name(user_params)
|> Map.put(:action, :validate)
|> to_form()
{:noreply, assign(socket, name_form: name_form)}
end
def handle_event("update_name", %{"user" => user_params}, socket) do
user = socket.assigns.current_user
case Accounts.apply_user_name(user, user_params, [validate_name: true]) do
{:ok, _changeset} ->
{:noreply, socket}
{:error, changeset} ->
{:noreply, assign(socket, :form, to_form(changeset))}
end
end
Accounts module, change_user_name returns an %Ecto.Changeset{}
for changing the user name:
def change_user_name(user, attrs \\ %{}, opts \\ []) do
User.name_changeset(user, attrs, opts)
end
def apply_user_name(user, attrs, opts \\ []) do
user
|> User.name_changeset(attrs, opts)
|> Ecto.Changeset.apply_action(:update)
end
User module contains validate_name changeset which validates name and checks if name in unique:
def validate_name(changeset, opts) do
changeset
|> validate_required([:name])
|> validate_length(:name, min: 2, max: 36, message: "username must be between 2 and 36 characters")
|> validate_format(:name, ~r/^[^\s]*$/, message: "cannot have a space at the end")
|> maybe_validate_unique_name(opts)
end
def name_changeset(user, attrs \\ %{}, opts \\ []) do
user
|> cast(attrs, [:name])
|> validate_name(opts)
|> case do
%{changes: %{name: _}} = changeset -> changeset
%{} = changeset -> add_error(changeset, :name, "did not change")
end
end
defp maybe_validate_unique_name(changeset, opts) do
if Keyword.get(opts, :validate_name, true) do
changeset
|> unsafe_validate_unique(:name, Elixirlore.Repo)
|> unique_constraint(:name)
else
changeset
end
end
I’d be very grateful for at least some indication where error may be located, thanks in advance.