Hello all,
I am getting KeyError for current_user in the liveview even though my socket contains current_user. Please go through below:
I have generated live view with this command:
mix phx.gen.live RegistrationSteps.Details UserDetail user_details user_id:references:users first_name last_name company:unique
So i did modify user_details by removing field of user_id and added association like this in the schema:
schema "user_details" do
field :first_name, :string
field :last_name, :string
field :company, :string
belongs_to :user, Accounts.User, type: :binary_id
timestamps(type: :utc_datetime)
end
In the changeset i added association constraint :
def changeset(user_detail, attrs) do
user_detail
|> cast(attrs, [:user_id,:first_name, :last_name, :company])
|> validate_required([:user_id, :first_name, :last_name, :company])
|> unique_constraint(:company)
|> assoc_constraint(:user)
end
For user schema i have added this has_one relation:
has_one :user_details, Details.UserDetail
In the context for creating user, i have added extra attribute like:
def create_user_detail(user, attrs \\ %{}) do
user
|> Ecto.build_assoc(:user_details)
|> UserDetail.changeset(attrs)
|> Repo.insert()
end
For live_session i have already setup on_mount function in the router inorder to fetch current_user from the socket assigns.
live_session :registration_session, on_mount: [{LngxWeb.Auth.UserAuth, :mount_current_user}] do
....
end
From the generated live view index.ex:
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end
defp apply_action(socket, :new, _params) do
# Logger.warning("Current Socket Connection: #{inspect(socket.assigns)}")
socket
|> assign(:page_title, "New User detail")
|> assign(:user_detail, %UserDetail{})
end
The part of index.html.heex Shows like this:
<.modal
:if={@live_action in [:new, :edit]}
id="user_detail-modal"
show
on_cancel={JS.patch(~p"/registration/details")}
>
<.live_component
module={MyWeb.UserDetailLive.FormComponent}
id={@user_detail.id || :new}
title={@page_title}
action={@live_action}
user_detail={@user_detail}
patch={~p"/registration/details"}
/>
</.modal>
For the handle_event save in form_component, i tried to pass the current_user parameter from the socket assigns.
def handle_event(
"save",
%{"user_detail" => user_detail_params},
socket
) do
current_user = socket.assigns.current_user
save_user_detail(socket, socket.assigns.action, user_detail_params, current_user)
end
So When i click on save i am getting 2 errors:
- KeyError current_user not found:
- user_id cannot be null
**(KeyError) key :current_user not found in:** %{
id: :new,
title: "New User detail",
form: %Phoenix.HTML.Form{
source: #Ecto.Changeset<
action: :validate,
changes: %{first_name: "bad", last_name: "bad", company: "bad"},
errors: [user_id: {"can't be blank", [validation: :required]}],
data: #Lngx.RegistrationSteps.Details.UserDetail<>,
valid?: false,
...
I made sure that socket.assigns
contains current_user
.
Beginner in elixir and phoenix, help and some resources on building live views with table associations will be much appreciated. Thank you.