I have the following in my Comment model (Phoenix 1.2):
schema "comments" do
belongs_to :parent, Test.Comment
belongs_to :user, Test.User
belongs_to :post, Test.Post
has_many :children, Test.Comment, foreign_key: :parent_id
end
During migrations I had added:
create table(:comments) do
add :parent_id, :integer
add :user_id, references(:users, on_delete: :delete_all)
add :post_id, references(:posts, on_delete: :delete_all)
end
I wanted to show the blog post, as well the comments and the replies on the comments (nested comments like reddit) on the post show page.
The comments and the nested comments are getting created correctly, but I am not able to resolve displaying the nested comments with the 'user' preloaded on the post/show page.
So in the post_controller, show function I have this:
post = Post
|> Repo.get(id)
|> Repo.preload(comments: from(c in Comment, order_by: [desc: c.inserted_at]),
comments: :user, comments: :parent, comments: :children)
In the _comment.html.eex, the following line I placed throws the error #Ecto.Association.NotLoaded<association :user is not loaded>
:
User: <%= @comment.user.username %>
Any help with this will be appreciated.
Update 1:
Output of running post = Post |> Repo.get(48) |> Repo.preload(comments: from(c in Comment, order_by: [desc: c.votes_up]), comments: :user, comments: :parent, comments: :children)
as a sample post with comments and reply to comments.
%Test.Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">,
category: "new",
comments: [%Test.Comment{__meta__: #Ecto.Schema.Metadata<:loaded,
"comments">,
body: "hello there", children: [], id: 69,
inserted_at: ~N[2017-07-28 21:52:49.636919],
parent: nil, parent_id: nil,
post: #Ecto.Association.NotLoaded<association :post is not loaded>,
post_id: 48,
updated_at: ~N[2017-07-28 21:52:49.636933],
user: %Test.User{username: "dude",
comments: #Ecto.Association.NotLoaded<association :comments is not
loaded>,
...},
user_id: 11},
%Test.Comment{__meta__: #Ecto.Schema.Metadata<:loaded, "comments">,
body: "working there?",
children: [%Test.Comment{__meta__: #Ecto.Schema.Metadata<:loaded,
"comments">,
body: "real child reply should be seen in the show post page",
children: #Ecto.Association.NotLoaded<association :children is not
loaded>,
id: 85, inserted_at: ~N[2017-08-03 21:52:37.116894],
parent: #Ecto.Association.NotLoaded<association :parent is not
loaded>,
parent_id: 70,
post: #Ecto.Association.NotLoaded<association :post is not loaded>,
post_id: 48,
user: #Ecto.Association.NotLoaded<association :user is not loaded>,
user_id: 5}],
user: %Test.User{username: "dude", ...
Update 2:
In the post/show template this is what I have to display the comments:
<%= for comment <- @post.comments do %>
<%= render "_comment.html", comment: comment, conn: @conn, post: @post %>
<% end %>
And then in the _comment.html partial I do the following to display the parent comment and its nested children comments:
<p>User: <%= @comment.user.username %></p>
<p>@comment.body</p>
<% unless Enum.empty?(@comment.children) do %>
<%= for child_comment <- @comment.children do %>
<ul class="nested_comment">
<%= render "_comment.html", comment: child_comment, conn: @conn, post: @post %>
</ul>
<% end %>
<% end %>