0

I am wrapping my head around the Rails framework and routes. I am building a site where users can post Rails articles and tips and I've already added a ton of functionality to my site but I am having an issue with nested resources. I want my users to create post. I also want the same user and other users to leave comments on the post. Now, the tricky part is that I need a way for them to edit their own comment. So once they go to a post>comment>edit, I am receiving a No route matches [GET] "/posts/48/comments/edit" and this is from the Post show template. For tht particular post, I can tell by the error that it cannot find the id of that comment to edit it. I am sure that this is nested resources issue but I cant wrap my head on it. Looking at my code, everything seems in tact to me. Any ideas? Thanks in advance for any insight.

routes.rb file

PostitTemplate::Application.routes.draw do
  root to: 'posts#index'

  get '/register', to: 'users#new'
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'
  get '/logout', to: 'sessions#destroy'

  resources :users, only: [:create, :edit, :update]

  resources :posts, except: [:destroy] do
    member do
      post 'vote'
    end

    resources :comments, only: [:create, :edit, :update] do
      member do
        post 'vote'
      end
    end
  end

  resources :categories, only: [:new, :create]
end

comments_controller

class CommentsController < ApplicationController
  before_action :require_user

  def create
    @post = Post.find(params[:post_id])
    @comment = Comment.new(params.require(:comment).permit(:body))
    @comment.post = @post
    @comment.creator = current_user

    if @comment.save
      flash[:notice] = "Your comment was created!"
      redirect_to post_path(@post)
    else
      render 'posts/show'
    end
  end

  def edit
    @comment = Comment.find(params[:id])
    @post = Post.find(params[:post_id])
  end

  def update
    @comment = Comment.find(params[:id])
    if @comment.update(comment_params)
      flash[:notice] = "You updated your comment!"
      redirect_to post_path
    else
      render :edit
    end
  end

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

  def set_comment
    @comment = Comment.find(params[:id])
  end
end

posts_controller

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :vote]
  before_action :require_user, only: [:new, :create, :edit, :update, :vote]
  before_action :require_creator, only:[:edit, :update]

  def index
    @posts = Post.all.page(params[:page]).per_page(10)
  end

  def show
    @comment = Comment.new
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
    @post.creator = current_user

    if @post.save
      flash[:notice] = "You created a post!"
      redirect_to posts_path
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @post.update(post_params)
      flash[:notice] = "You updated the post!"
      redirect_to post_path(@post)
    else
      render :edit
    end
  end

  def vote
    Vote.create(voteable: @post, creator: current_user, vote: params[:vote])

    respond_to do |format|
      format.js { render :vote } # Renders views/posts/vote.js.erb
    end
  end

  private
  def post_params
    params.require(:post).permit(:url, :title, :description)
  end

  def set_post
    @post = Post.find(params[:id])
  end

  def require_creator
    access_denied if @post.creator != current_user
  end
end

show.html.erb(This is the show post template and on line 33, I want to link to the comments controller edit action)

<div class="page-header">
  <h2>
    <%= @post.title %>
    <small>
      posted by <%= link_to @post.creator.username %> about <%= time_ago_in_words(@post.created_at) + ' ago' %>
      | <%= link_to 'check out the link', fix_url(@post.url) %> |
      <%= link_to 'edit', edit_post_path(@post) %>
    </small>
  </h2>
</div>

<h3><%= @post.description %></h3>
  <%= render 'shared_partials/errors', errors_obj: @comment %>

  <%= form_for [@post, @comment] do |f| %>
    <%= f.text_area :body, :class=> "input", :placeholder=> "Comment goes here", :rows => "6" %>
    </br>
    <div class="button">
    <%= f.submit "Create a comment", class: 'btn btn-primary' %>
    </div>
  <% end %>

<div class="page-header">
  <h4>All Comments</h4>
</div>
<% @post.comments.each do |comment| %>
  <div class="comments">
    <h5><%= comment.body %></h5>
      <li>
       <small class="muted">
        posted by <%= link_to comment.creator.username %> about <%= time_ago_in_words(comment.created_at) + ' ago' %>
        <% if logged_in? && (comment.creator == current_user) %> |
        <%= link_to 'edit', edit_post_comment_path(@post, @comment) %> |
          <i class="icon-user icon"></i>
        <% end %>
      </small>
      </li>
  </div>
<% end %>

Finally my rake routes

root_path    GET     /   posts#index
register_path    GET     /register(.:format)     users#new
login_path   GET     /login(.:format)    sessions#new
POST     /login(.:format)    sessions#create
logout_path  GET     /logout(.:format)   sessions#destroy
users_path   POST    /users(.:format)    users#create
edit_user_path   GET     /users/:id/edit(.:format)   users#edit
user_path    PATCH   /users/:id(.:format)    users#update
PUT  /users/:id(.:format)    users#update
vote_post_path   POST    /posts/:id/vote(.:format)   posts#vote
vote_post_comment_path   POST    /posts/:post_id/comments/:id/vote(.:format)     comments#vote
post_comments_path   POST    /posts/:post_id/comments(.:format)  comments#create
edit_post_comment_path   GET     /posts/:post_id/comments/:id/edit(.:format)     comments#edit
post_comment_path    PATCH   /posts/:post_id/comments/:id(.:format)  comments#update
PUT  /posts/:post_id/comments/:id(.:format)  comments#update
posts_path   GET     /posts(.:format)    posts#index
POST     /posts(.:format)    posts#create
new_post_path    GET     /posts/new(.:format)    posts#new
edit_post_path   GET     /posts/:id/edit(.:format)   posts#edit
post_path    GET     /posts/:id(.:format)    posts#show
PATCH    /posts/:id(.:format)    posts#update
PUT  /posts/:id(.:format)    posts#update
categories_path  POST    /categories(.:format)   categories#create
new_category_path    GET     /categories/new(.:format)   categories#new
4

1 回答 1

0

代替

<%= link_to 'edit', edit_post_comment_path(@post, @comment) %>

<%= link_to 'edit', edit_post_comment_path(@post, comment) %>

您需要传递当前评论,而不是新评论。

此外,您不一定必须嵌套comment资源。

于 2013-09-28T15:58:47.377 回答