重构嵌套路由,如何解决此redirect_to?

时间:2015-05-15 16:31:37

标签: ruby-on-rails ruby ruby-on-rails-3 routing refactoring

我正在为我一直在做的项目工作。我刚刚介绍了重构我的嵌套路由。以下是更改。

的routes.rb

   resources :topics do 
     resources :posts, except: [:index] do
       resources :comments, only: [:create, :destroy]
     end
   end

  resources :topics do
    resources :posts, except: [:index]
  end

  resources :posts, only: [] do
    resources :comments, only: [:create, :destroy]
  end

在此之后我的指示如下:

  

运行rake路由以查看此更改路由的方式。然后做   使用这些新的,较浅的路线对重构进行更改:

     

更改评论/ _comment.html.erb和评论路径   comments / _form.html.erb partials。

     

更改CommentsController操作,使它们不再存在   初始化@topic。

     

从@post派生@topic,因为我们仍然需要redirect_to @post   创建或销毁评论后的页面。此外,@ post是   仍然嵌套在@topic下。

     

访问帖子,然后删除并创建评论以测试这个新的浅层   嵌套。

佣金路线

▶ rake routes
                  Prefix Verb   URI Pattern                                Controller#Action
         comments_create GET    /comments/create(.:format)                 comments#create
        new_user_session GET    /users/sign_in(.:format)                   devise/sessions#new
            user_session POST   /users/sign_in(.:format)                   devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)                  devise/sessions#destroy
           user_password POST   /users/password(.:format)                  devise/passwords#create
       new_user_password GET    /users/password/new(.:format)              devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format)             devise/passwords#edit
                         PATCH  /users/password(.:format)                  devise/passwords#update
                         PUT    /users/password(.:format)                  devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)                    devise/registrations#cancel
       user_registration POST   /users(.:format)                           devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)                   devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)                      devise/registrations#edit
                         PATCH  /users(.:format)                           devise/registrations#update
                         PUT    /users(.:format)                           devise/registrations#update
                         DELETE /users(.:format)                           devise/registrations#destroy
       user_confirmation POST   /users/confirmation(.:format)              devise/confirmations#create
   new_user_confirmation GET    /users/confirmation/new(.:format)          devise/confirmations#new
                         GET    /users/confirmation(.:format)              devise/confirmations#show
                    user PATCH  /users/:id(.:format)                       users#update
                         PUT    /users/:id(.:format)                       users#update
             topic_posts POST   /topics/:topic_id/posts(.:format)          posts#create
          new_topic_post GET    /topics/:topic_id/posts/new(.:format)      posts#new
         edit_topic_post GET    /topics/:topic_id/posts/:id/edit(.:format) posts#edit
              topic_post GET    /topics/:topic_id/posts/:id(.:format)      posts#show
                         PATCH  /topics/:topic_id/posts/:id(.:format)      posts#update
                         PUT    /topics/:topic_id/posts/:id(.:format)      posts#update
                         DELETE /topics/:topic_id/posts/:id(.:format)      posts#destroy
                  topics GET    /topics(.:format)                          topics#index
                         POST   /topics(.:format)                          topics#create
               new_topic GET    /topics/new(.:format)                      topics#new
              edit_topic GET    /topics/:id/edit(.:format)                 topics#edit
                   topic GET    /topics/:id(.:format)                      topics#show
                         PATCH  /topics/:id(.:format)                      topics#update
                         PUT    /topics/:id(.:format)                      topics#update
                         DELETE /topics/:id(.:format)                      topics#destroy
           post_comments POST   /posts/:post_id/comments(.:format)         comments#create
            post_comment DELETE /posts/:post_id/comments/:id(.:format)     comments#destroy
                   about GET    /about(.:format)                           welcome#about
                    root GET    /                                          welcome#index

_comment.html.erb

<% @comments.each do |comment| %>

<div class="media">
  <div class="media-left">
    <%= image_tag(comment.user.avatar.small.url, class: "media-object") if comment.user.try(:avatar) %>
  </div>
  <div class="media-body">
    <small>
      <% comment.user.name %> commented <%= time_ago_in_words(comment.created_at) %> ago
      <% if policy(comment).destroy? %>
        | <%= link_to "Delete", [@topic, @post, comment], method: :delete %>
      <% end %>
    </small>
    <p><%= comment.body %>
  </div>
</div>
<% end %>

我特意将第11行更改为:

| <%= link_to "Delete", [@post, comment], method: :delete %>

_form.html.erb

<%= form_for [topic, post, comment] do |f| %>
  <% if comment.errors.any? %>
    <div class="alert alert-danger">
      <h4>There are <%= pluralize(comment.errors.count, "error") %>.</h4>
      <ul>
        <% comment.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
    <% end %>

    <div class="form-inline">
    <%= form_group_tag(comment.errors[:body]) do %>
      <%= f.label :body %>
      <%= f.text_field :body, class: 'form-control'%>
    <% end %>

    <div class="form-group">
      <%= f.submit "Comment", class: 'btn btn-default' %>
    </div>
  </div>
  <% end %>

我改为第一行:

<%= form_for [post, comment] do |f| %>

现在,我可以在启动Rails服务器时查看该项目。我不确定我将如何进行最后一步。

  

从@post派生@topic,因为我们仍然需要redirect_to @post   创建或销毁评论后的页面。此外,@ post是   仍然嵌套在@topic下。

这是我的 comments_controller.rb

class CommentsController < ApplicationController
  def create
    # find topic by id
    # @topic = Topic.find(params[:topic_id])
    # find post id through topic
    @post = Post.find(params[:post_id])
    # comments on post
    @comments = @post.comments

    @comment = current_user.comments.build(params.require(:comment).permit(:body, :post_id))
    @comment.post = @post


    authorize @comment
    if @comment.save
      flash[:notice] = "Comment was created."
      redirect_to [@topic, @post]
    else
      flash[:error] = "Error saving the comment. Please try again."
      # must render the the page calling the form!!
      render 'posts/show'
    end
  end

  def new

  end

  def destroy
    @topic = Topic.find(params[:topic_id])
    @post = @topic.posts.find(params[:post_id])
    @comment = @post.comments.find(params[:id])

    authorize @comment
    if @comment.destroy
      flash[:notice] = "Comment was removed."
      redirect_to [@topic, @post]
    else
      flash[:error] = "Comment couldn't be deleted. Try again."
      redirect_to [@topic, @post]
    end
  end
end

正如您所看到的,显示帖子的路线是

topic_post GET    /topics/:topic_id/posts/:id(.:format)      posts#show

当我被告知删除@topic初始化时,我该怎么做?我试图将其包含在我当前修改过的代码中,但在尝试删除评论时收到此错误。

Processing by CommentsController#destroy as HTML
  Parameters: {"authenticity_token"=>"ocCSra0R/kcA+5MHVowZDNShghHhNUKYcO3yJaDuUKcZsRab90who4SuOK4MmS/4XXhycK0XZJ1UbS/n09aFEg==", "post_id"=>"2", "id"=>"7"}
  Topic Load (0.1ms)  SELECT  "topics".* FROM "topics" WHERE "topics"."id" = ? LIMIT 1  [["id", nil]]
Completed 404 Not Found in 7ms (ActiveRecord: 0.6ms)

最好的问候。

1 个答案:

答案 0 :(得分:3)

  

从@post派生@topic,因为我们仍然希望在创建或销毁评论后重定向到@post页面。此外,@ post仍然嵌套在@topic。

它说的不是通过Topic.find加载主题,而是从帖子中获取。 topic_id已不在params,因此您必须从帖子中获取def destroy @post = Post.find(params[:post_id]) @topic = @post.topic # ... the rest I think is unchanged end 。没什么大不了的,因为每个帖子都有一个主题,对吗?这必须是真的,否则你的路线会变得更浅。

这样的事情:

@topic

如果您真的想要,可以完全删除redirect_to [@post.topic, @post] ,并在重定向中执行此操作:

#pwd_not_equ{
opacity:0;
transition: opacity 2s;
color:red;
}