在post#show的末尾呈现一个新的评论表单



对于一个基本的博客应用程序(Post has_many comments),我想在post#show的末尾显示一个新的注释表单。但我一直被构建它和在web/templates/user/show.html.eex中渲染web/templates/comment/form.html.eex的机制所困扰。应用程序:

mix phoenix.new my_app
cd my_app
mix ecto.create
mix phoenix.gen.html Post posts content:string
mix phoenix.gen.html Comment comments content:string 
post_id:references:posts
mix ecto.migrate

web/models/post.ex

defmodule MyApp.Post do
  use MyApp.Web, :model
  schema "posts" do
    field :content, :string
    has_many :comments, MyApp.Comment
    timestamps
  end
  @required_fields ~w(content)
  @optional_fields ~w()
  def changeset(model, params \ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

web/models/comment.ex

defmodule MyApp.Comment do
  use MyApp.Web, :model
  schema "comments" do
    field :content, :string
    belongs_to :post, MyApp.Post
    timestamps
  end
  @required_fields ~w(content post_id)
  @optional_fields ~w()
  def changeset(model, params \ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

Post控制器中,我遇到了第一个问题。此代码不起作用(key :post not found in: %{}错误):

web/controller/post_controller.ex

[...]
def show(conn, %{"id" => id}) do
  post = Repo.get!(Post, id)
  changeset =
    conn.assigns.post
    |> build_assoc(:comments)
    |> Comment.changeset()
  render(conn, "show.html", post: post, changeset: changeset)
end
[...]

下一个问题是我不知道如何呈现表单

web/templates/post/show.html.eex

<h2>Show post</h2>
<ul>
  <li>
    <strong>Content:</strong>
    <%= @post.content %>
  </li>
</ul>
<%= render "comment/form.html", changeset: @changeset,
                        action: comment_path(@conn, :create) %>

我该怎么解决这个问题?

  1. web/controllers/post_controller.ex中,将conn.assigns.post仅替换为post,因为这是变量的实际名称。

  2. 要从另一个视图渲染模板(要从web/templates/post/show.html.eex渲染web/templates/comment/form.html.eex),需要传递目标模板的视图作为第一个参数:

    render MyApp.CommentView, "form.html", ...
    

    这是因为控制器中的renderPhoenix.Controller.render/4,而视图和模板中可用的是Phoenix.View.render/3,并且它们期望不同的参数。

最新更新