Phoenix: User-Story Relationship Issue on Create
Hello Elixir community,
I’m new to Elixir and Phoenix, and I’m currently building a simple blogging platform as a learning project. The application has a one-to-many relationship between users and stories, both created using Phoenix generators.
I’m trying to display the user’s email on the story_live
index page, but I’m encountering an issue when creating a new story. Here’s the relevant code:
# In lib/my_app/stories/story.ex
schema "stories" do
field :title, :string
field :body, :string
belongs_to :user, Blog.Accounts.User
timestamps(type: :utc_datetime)
end
# In web/live/story_live/index.ex
@impl true
def mount(_params, _session, socket) do
{:ok, stream(socket, :stories, Stories.list_stories())}
end
# In lib/my_app/stories.ex
def list_stories do
Story
|> preload(:user)
|> Repo.all()
end
# In web/live/story_live/index.html.heex
<.table
id="stories"
rows={@streams.stories}
row_click={fn {_id, story} -> JS.navigate(~p"/stories/#{story}") end}
>
<:col :let={{_id, story}} label="Title"><%= story.title %></:col>
<:col :let={{_id, story}} label="Body"><%= story.body %></:col>
<:col :let={{_id, story}} label="User Email"><%= story.user.email %></:col>
<!-- ... action columns ... -->
</.table>
<.modal :if={@live_action in [:new, :edit]} id="story-modal" show on_cancel={JS.patch(~p"/stories")}>
<.live_component
module={BlogWeb.StoryLive.FormComponent}
id={@story.id || :new}
title={@page_title}
action={@live_action}
story={@story}
user_id={@current_user.id}
patch={~p"/stories"}
/>
</.modal>
This setup works fine for displaying existing stories and their associated user emails. However, when I create a new story, the Elixir process crashes with the following error:
[error] GenServer #PID<0.1522.0> terminating
** (KeyError) key :email not found in: #Ecto.Association.NotLoaded<association :user is not loaded>
(blog 0.1.0) lib/blog_web/live/story_live/index.html.heex:17: anonymous fn/3 in BlogWeb.StoryLive.Index.render/1
(phoenix_live_view 0.20.17) lib/phoenix_live_view/diff.ex:391: Phoenix.LiveView.Diff.traverse/7
...
The error suggests that the :user
association is not loaded for the newly created story. This is puzzling because both the index and create actions use the same list_stories
context function, which preloads the :user
details.
I’m particularly confused by these aspects:
- Why does the error occur only for newly created stories?
- Why doesn’t the
preload(:user)
inlist_stories
function seem to be working for new stories? - Is there a difference in how Phoenix handles newly created records vs. existing ones in LiveView?
I would greatly appreciate any insights into this behavior. I’m eager to understand and learn from this issue to improve my grasp of Phoenix and Elixir.
Thank you in advance for your time and expertise!