将验证错误数组从一个控制器传递到另一个控制器

时间:2018-01-07 23:01:10

标签: ruby-on-rails

评论 belongs_to 发布发布 has_many 评论,评论模型如下:

class Comment < ApplicationRecord
  belongs_to :post
  belongs_to :user
  validates :text, presence: true
end

添加新评论的表单位于帖子展示视图中,如下所示:

<%= form_with(model: [ @post, @post.comments.build ], local: true) do |form| %>
    <% if @comment.errors.any?%>
        <div id="error_explanation">
          <ul>
            <% @comment.errors.messages.values.each do |msg| %>
              <%msg.each do  |m| %>
                 <li><%= m %></li>
              <%end %>
             <% end %>
          </ul>
        </div>
    <% end %>
    <p>
       <%= form.text_area :text , {placeholder: true}%>
    </p>

    <p>
       <%= form.submit %>
    </p>
<% end %>

评论创建操作,如下所示:

class CommentsController < ApplicationController

def create
    @post = Post.find(params[:post_id])
    @comment = Comment.new(comment_params)
    @comment.post_id = params[:post_id]
    @comment.user_id = current_user.id
    if @comment.save
        redirect_to post_path(@post)
    else
        render 'posts/show'
    end
end



private
    def comment_params
      params.require(:comment).permit(:text)
    end
end

我需要渲染帖子/显示页面以显示评论验证错误,但问题是我在 CommentsController 控制器而不是PostsController所以页面中使用的所有对象/ show view将为null。

如何将@comment对象传递给pages / show? 我想过使用 flash 数组,但我正在寻找更传统的方式。

1 个答案:

答案 0 :(得分:2)

是的,呈现pages/show只会使用视图模板,而不是动作,因此您在pages#show控制器操作中定义的任何内容都将无法使用。在@comment操作中定义comments#create时,PostsController将可用。在没有看到pages#show我不知道您在ApplicationController操作中加载了什么内容的情况下,您可以考虑将两者中所需的任何内容移到remote: true上的方法中,然后从两个地方打电话。另一种选择是通过AJAX(local: true而不是表单上的pages/show.html.erb)将您的评论过程更改为工作,并使用JS进行响应,旨在重新呈现评论表单(您可以将其移至部分在comments#createcomments#create响应中使用。

上面代码中的其他一些注释 - 在@comment = @post.comments.new(comment_params) 中,您可以使用:

post_id

以避免需要手动设置@comment pages#show

对于表单,我很想在@comment = @post.comments.build 中设置新评论:

pages#show

然后在表单中引用它,如果您在comments#create<%= form_with(model: [ @post, @comment ], local: true) do |form| %> 之间重复使用它会更容易:

<Alloy>
   <NavigationWindow>
       <TabGroup>
          <Tab>
            <Window>

               <LeftNavButton>
                  <Button title="Back" onClick="...." />
               </LeftNavButton>

               .................. 

            </Window>
          </Tab>

          <Tab>
            <Window>

               <LeftNavButton>
                  <Button title="Back" onClick="...." />
               </LeftNavButton>

               .................. 

            </Window>
          </Tab>

       </TabGroup>  
   </NavigationWindow>
</Alloy>

希望有所帮助!