Current_user present in socket.assigns for LiveView page load but not for form submission

I want users to be able to create posts owned by the current user. In form_component.ex, I have this:

  defp save_post(socket, :new, post_params) do
    case Posts.create_post(
           Map.merge(
             post_params,
             %{"user_id" => socket.assigns.current_user}
           )
         ) do

When I test this, I get a key :current_user not found error. The relevant test section looks like this:

    test "saves new post", %{conn: conn} do
      {:ok, index_live, _html} = live(conn, ~p"/posts")

      assert index_live |> element("a", "New Post") |> render_click() =~
               "New Post"

      assert_patch(index_live, ~p"/posts/new")

      assert index_live
             |> form("#post-form", post: @invalid_attrs)
             |> render_change() =~ "can't be blank"

      assert index_live
             |> form("#post-form", post: @create_attrs)
             |> render_submit()

The current_user key DOES exist in the session when live(conn, ~p"/posts") is called, and when assert_patch is run, but is somehow not available when render_submit triggers the “save” action and I cannot for the life of me figure out why. Running Phoenix 1.7.0. Anyone know what might be going on?

Is FormComponent a LiveComponent? If so you need to find the place where it is rendered and supply @current_user to its assigns. Probably something like this:

<.live_component
    module={MyAppWeb.PostLive.FormComponent}
    id={@post.id || :new}
    current_user={@current_user} # add this
    title={@page_title}
    action={@live_action}
    post={@post}
    navigate={~p"/posts"}
  />

Ah; thanks, that worked! So the assigns only contain what’s explicitly passed in for LiveComponents?

Correct, all assigns must be given explicitly, for LiveComponents and function components :slight_smile:

1 Like