Help with ecto association 1.4

Post not loaded with user ecto association I need an example because I’m a newbie and for some reason it’s not working

Hi @ankhnaton,
Do you have like a specific error message?
It could be that you have not preload ed the post association

1 Like

[
%Three.Accounts.User{
meta: #Ecto.Schema.Metadata<:loaded, “users”>,
email: "ben@ben.com",
id: 1,
inserted_at: ~N[2019-08-27 21:51:43],
password: nil,
password_confirmation: nil,
password_hash: “$2b$12$AO8kkVQMw/VnPNRxksqflOO1XIMxWbH.d52PDYHbUU/5zGRvNSgQ.”,
posts: #Ecto.Association.NotLoaded,
updated_at: ~N[2019-08-27 21:51:43],
username: “user”
}
]

It would be easier if You show your query…

You need to preload.

Example:

 49     perfume = Fragrance.get_perfume!(id)
  50               |> Fumigate.Repo.preload([
  51                 :accords,
  52                 :companies,
  53                 perfume_note_joins: :note
  54               ])

In your case it could be:

 49     user = User.get_user!(id)
  50               |> YourApp.Repo.preload([
  51                 :posts
  54               ])
2 Likes

Put this in the controller

def create(conn, %{ “user_id” => user_id, “post” => post_params}) do
user = Repo.get!(User, user_id)

case Blog.create_post(user, post_params) do
  {:ok, post} ->
    conn
    |> Repo.preload(:user)
    |> put_flash(:info, "Post created successfully.")
    |> redirect(to: Routes.post_path(conn, :show, post, user))

  {:error, %Ecto.Changeset{} = changeset} ->
    render(conn, "new.html", changeset: changeset)
end

end

Why are you trying to preload user if you already have it as an argument?

if you’re trying to assign posts to users you can do a has_many/belongs to relation between the user and the post. In which case you would only need to pass user_id to the post.

because i got this user_id error

lib/main_web/controllers/post_controller.ex
def create(conn, %{ “user_id” => user_id, “post” => post_params}) do
user = Repo.get!(User, user_id)
case Blog.create_post(user, post_params) do
{:ok, post} ->
conn

i followed elixircast Adding Comments with Ecto Associations to add user to post and i keep getting errors

def create(conn, %{"chart" => chart_params}) do
    current_user = Plug.Conn.get_session(conn, :current_user_id)
    case Budgets.create_chart(current_user, chart_params) do
      {:ok, chart} ->
        conn
        |> put_flash(:info, "Chart created successfully.")
        |> redirect(to: Routes.chart_path(conn, :show, chart))

      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end
  def create_chart(user, attrs \\ %{}) do
    %Chart{}
    |> change(%{"user_id": user})
    |> apply_changes
    |> Chart.changeset(attrs)
    |> Repo.insert()
  end

In this code above, I take the user id , pass it to the create function and add it to the changeset before inserting it into the db. You can use the id to preload if you used a belongs to relation from the post(chart) to the user.

found quoted keyword “user_id” but the quotes are not required. Note that keywords are always atoms, even when quoted. Similar to atoms, keywords made exclusively of Unicode letters, numbers, underscore, and @ do not require quotes this is what my editor is giving me

def create_post(user, attrs \ %{}) do
%Post{}
|> Repo.preload(:user)
|> Post.changeset(attrs)
|> Repo.insert()
end

this dosent work either its giving me an error

if user_id is not in url this gives you error. And you should get user_id in Plug.Conn

also this line is wrong. this line is equal to Repo.preload(conn, :user). To preload user first argument should be a Post not conn

And always share what errors you get

can you show me a controller example with a context example

def create_post(user_id, attrs \ %{}) do
%Post{user_id: user_id}
|> Post.changeset(attrs)
|> Repo.insert()
end

You need just user_id for that function in Three.Blog module. And call it in controller. Don’t preload anything

2 Likes