Forms 在Phoenix中处理多种表单的变更集
我想写一个论坛网站。在特定主题的页面上,用户可以添加新帖子,也可以评论以前的帖子(他们不能评论评论)。我的第一个想法是为新帖子和每条评论创建单独的表单,我为所有这些表单创建了单独的变更集。但是,当添加新的帖子/评论失败时,使用这种方法,我必须再次创建所有新的变更集,并找到真正使用的变更集,并将其替换为带有错误消息的变更集,我认为这有点难看。在凤凰城有更好的方法吗Forms 在Phoenix中处理多种表单的变更集,forms,elixir,phoenix-framework,ecto,Forms,Elixir,Phoenix Framework,Ecto,我想写一个论坛网站。在特定主题的页面上,用户可以添加新帖子,也可以评论以前的帖子(他们不能评论评论)。我的第一个想法是为新帖子和每条评论创建单独的表单,我为所有这些表单创建了单独的变更集。但是,当添加新的帖子/评论失败时,使用这种方法,我必须再次创建所有新的变更集,并找到真正使用的变更集,并将其替换为带有错误消息的变更集,我认为这有点难看。在凤凰城有更好的方法吗 def index(conn, %{"topic_id" => topic_id}, _current_user) do t
def index(conn, %{"topic_id" => topic_id}, _current_user) do
topic = Forum.get_topic!(topic_id)
render(
conn,
"index.html",
topic: topic,
changesets: create_changesets(topic.posts))
end
def add_post(conn, %{"topic_id" => topic_id, "post" => post_params}, current_user) do
case Forum.create_post(current_user, topic, post_params) do
{:ok, _post} ->
redirect(conn, to: topic_path(conn, :index, topic_id))
{:error, changeset} ->
topic = Forum.get_topic!(topic_id)
render(
conn,
"index.html",
topic: topic,
changesets: create_changesets(topic.posts, changeset))
end
end
def add_comment(conn, %{"topic_id" => topic_id, "post_id" => post_id, "comment" => comment_params}, current_user) do
post = Forum.get_post!(post_id)
case Forum.create_comment(current_user, post, comment_params) do
{:ok, _comment} ->
redirect(conn, to: topic_path(conn, :index, topic_id))
{:error, changeset} ->
topic = Forum.get_topic!(topic_id)
render(
conn,
"index.html",
topic: topic,
changesets: create_changesets(topic.posts, changeset))
end
end
# ugly part
defp create_changesets(posts) do
create_changesets(posts, Forum.change_post(%Forum.Post{}))
end
defp create_changesets(posts, %Ecto.Changeset{data: %Forum.Post{}} = changeset) do
comments_changesets = for _ <- posts do
Forum.change_comment(%Forum.Comment{})
end
%{posts: changeset, comments: comments_changesets}
end
defp create_changesets(posts, %Ecto.Changeset{data: %Forum.Comment{}} = changeset) do
comments_changesets = for post <- posts do
if post.id == changeset.data.forum_post_id do
changeset
else
Forum.change_comment(%Forum.Comment{})
end
end
%{posts: Forum.change_post(%Forum.Post{}), comments: comments_changesets}
end
def索引(conn,%{“topic\u id”=>topic\u id},\u当前用户)是否
topic=Forum.get_topic!(主题id)
渲染(
康涅狄格州,
“index.html”,
主题:主题,,
变更集:创建_变更集(topic.posts))
结束
def add_post(conn,%%{“topic_id”=>topic_id,“post”=>post_params},当前用户)do
案例论坛。创建帖子(当前用户、主题、帖子参数)
{:好的,{u post}->
重定向(连接,到:主题\路径(连接,索引,主题\ id))
{:错误,变更集}->
topic=Forum.get_topic!(主题id)
渲染(
康涅狄格州,
“index.html”,
主题:主题,,
变更集:创建_变更集(topic.posts,变更集))
结束
结束
def add_comment(conn,%%{“topic_id”=>topic_id,“post_id”=>post_id,“comment”=>comment_params},当前用户)do
post=Forum.get_post!(邮政编码)
案例论坛。创建评论(当前用户、帖子、评论参数)吗
{:好的,_comment}->
重定向(连接,到:主题\路径(连接,索引,主题\ id))
{:错误,变更集}->
topic=Forum.get_topic!(主题id)
渲染(
康涅狄格州,
“index.html”,
主题:主题,,
变更集:创建_变更集(topic.posts,变更集))
结束
结束
#丑恶的部分
defp创建变更集(POST)do
创建变更集(posts,Forum.change\u post(%Forum.post{}))
结束
defp create_变更集(posts,%Ecto.Changeset{data:%Forum.Post{}}=Changeset)do
comments\u changesets=for\u我不完全确定你在问什么。你能澄清一下吗?我在问题中添加了控制器的代码。正如您所看到的,我的代码几乎一半都在为表单构建变更集。我的问题是关于设计。创建一个单独的表单来为每个帖子添加评论是个好主意吗?如果是这样的话,我能更好地处理这个变更集吗?为了澄清一点,让我们想象一下,除了注释之外,我可以添加一个函数,在帖子上添加某种反应(如等),然后每次我都必须为反应生成一个变更集列表,这对我来说似乎是个坏主意。
<%= @topic.title %>
<ul>
<%= render "post_form.html", changeset: @changesets.posts,
action: topic_path(@conn, :add_post, @topic.id) %>
<%= for {post, comment_changeset} <- Enum.zip(@topic.posts, @changesets.comments) do %>
<li>
<%= post.inserted_at %>
<%= post.text %>
</li>
<ul>
<%= for comment <- post.comments do %>
<li><%= comment.text %> - <%= comment.inserted_at %></li>
<% end %>
<%= render "comment_form.html", changeset: comment_changeset,
action: topic_path(@conn, :add_comment, @topic.id, post.id) %>
</ul>
<% end %>
</ul>