Nested association preloads doesn't work

Hello! I have structure: Post -> Author and Post -> Shared -> Author. But my nested associations for Author inside Shared doesn’t work.

I got error: ** (KeyError) key :author not found in: #Ecto.Association.NotLoaded<association :shared is not loaded>

Here is my code:

def list_posts_by_author(params) do
{stamp, “”} = Integer.parse(params[“stamp”])
author = params[“author_id”]

stamp = 
  with {:ok, stamp} <- DateTime.from_unix(stamp, :millisecond) do
    DateTime.to_naive(stamp) else err -> err
  end

(from p in Post, 

  preload: [shared: :author],
  preload: [:author],
  where: p.inserted_at < ^stamp,
  where: p.author_id == ^author) 

  |> order_by(desc: :inserted_at)
  |> Repo.all()

end

Thank you!

Welcome, You should show the schemas You are using to have a better answer. In particular Shared schema…

You sure you are getting this error from this query? Because I saw this error when we are calling some nested schema attribute from views and its association is not preloaded.

On side note you can optimise your query:

      (from p in Post, 
        preload: [:author, [shared: :author]],
        where: p.inserted_at < ^stamp and p.author_id == ^author),           
        |> order_by(desc: :inserted_at)
        |> Repo.all()

This is my schema, shared is post

  use Ecto.Schema
  import Ecto.Changeset


  schema "posts" do
    field :text_title, :string
    field :text, :string

    belongs_to :author, Blogus.Earth.Author
    belongs_to :shared, Blogus.Earth.Post

    timestamps()
  end

  @doc false
  def changeset(post, attrs) do
    post
    |> cast(attrs, [:text_title, :author_id, :text, :shared_id])
    |> validate_required([:author_id])
  end  

This is my migration to create shared_id

use Ecto.Migration

def change do
alter table(“posts”) do
add :shared_id, references(:posts, on_delete: :nothing)
end

create index(:posts, [:shared_id])

end

Here is my view:

def render("post.json", %{post: post}) do if Ecto.assoc_loaded?(post.author) do %{id: post.id, text: post.text, text_title: post.text_title, shared: render_one(post.shared, PostView, "post.json"), author: render_one(post.author, AuthorView, "author.json") } else %{id: post.id, text: post.text, text_title: post.text_title, author_id: post.author_id} end end

Yes, im getting error in view, but because of not preloaded association.