【发布时间】:2017-08-24 22:32:38
【问题描述】:
我的评论模型(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
在迁移期间我添加了:
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
我想在帖子显示页面上显示博客文章,以及 cmets 和对 cmets 的回复(嵌套 cmets,如 reddit)。
cmets 和嵌套 cmets 已正确创建,但 我无法解决在发布/显示页面上预加载“用户”的情况下显示嵌套 cmets。
所以在 post_controller 中,显示函数我有这个:
post = Post
|> Repo.get(id)
|> Repo.preload(comments: from(c in Comment, order_by: [desc: c.inserted_at]),
comments: :user, comments: :parent, comments: :children)
在 _comment.html.eex 中,我放置的以下行抛出错误#Ecto.Association.NotLoaded<association :user is not loaded>:
User: <%= @comment.user.username %>
对此的任何帮助将不胜感激。
更新 1:
运行post = Post |> Repo.get(48) |> Repo.preload(comments: from(c in Comment, order_by: [desc: c.votes_up]), comments: :user, comments: :parent, comments: :children) 的输出作为与 cmets 的示例帖子并回复 cmets。
%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", ...
更新 2:
在 post/show 模板中,这是我必须显示 cmets 的内容:
<%= for comment <- @post.comments do %>
<%= render "_comment.html", comment: comment, conn: @conn, post: @post %>
<% end %>
然后在 _comment.html 部分中,我执行以下操作来显示父注释及其嵌套的子 cmets:
<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 %>
【问题讨论】:
-
您可以发布该预加载执行的查询吗?我运行了一个类似的查询,
post |> Map.get(:comments) |> Enum.at(0) |> Map.get(:user)为我返回了一个%User{}。 -
嗨 @Dogbert 我在更新中添加了在 iex 中运行
post = Post |> Repo.get(48) |> Repo.preload(comments: from(c in Comment, order_by: [desc: c. inserted_at]), comments: :user, comments: :parent, comments: :children)的查询结果,这与后控制器中的完全相同 -
据我所知,该结果确实包含
Enum.at(post.comments, 0).user.username的值。这不是您要在模板中访问的值吗?模板中的@comment是什么? -
嘿@Dogbert,我在第二次更新中添加了帖子/节目模板和_comment.html 模板中的内容,以回答您关于
@comment的问题