Reputation: 131
I was following this tutorial http://www.sitepoint.com/nested-comments-rails/ to implement nested comments for an image board. It worked fine until I made "comments" belong to "boards" and then had to nest my routes.
Here are my routes:
Rails.application.routes.draw do
root "boards#index"
devise_for :users do
get '/users/sign_out' => 'devise/sessions#destroy'
end
resources :boards do
resources :comments
get '/comments/new/(:parent_id)', to: 'comments#new', as: :new_comment
get '/comments/(:parent_id)', to: 'comments#destroy', as: :delete_comment
get '/comments/edit/(:parent_id)', to: 'comments#edit', as: :edit_comment
end
end
Here is my form:
<%= form_for [@board, @comment] do |f| %>
<% if @comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% @comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :parent_id %>
<div class="form-group">
<% if @comment.parent_id == nil %>
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<% else %>
<% nil %>
<% end %>
</div>
<div class="form-group">
<%= f.radio_button(:user_id, current_user.id) %>
<%= f.label(:user_id, "I want to post as myself") %>
<%= f.radio_button(:user_id, nil) %>
<%= f.label(:user_id, "I want to post anonymously") %>
</div>
<div class="form-group">
<%= f.label :content %>
<%= f.text_area :content, class: 'form-control', required: true %>
</div>
<div class="form-group">
<%= f.label :image %>
<%= f.file_field :image %>
</div>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
And here is my controller:
class CommentsController < ApplicationController
def index
@comments = Comment.hash_tree
end
def new
@comment = Comment.new(parent_id: params[:parent_id])
end
def edit
@comment = Comment.find(params[:parent_id])
end
def create
if params[:comment][:parent_id].to_i > 0
parent = Comment.find_by_id(params[:comment].delete(:parent_id))
@comment = parent.children.build(comment_params)
else
@comment = Comment.new(comment_params)
end
if @comment.save
redirect_to root_url
else
render 'new'
end
end
def update
@comment = Comment.find(params[:id])
if @comment.update(comment_params)
redirect_to @comment
else
render 'edit'
end
end
def make_parent
@comment.parent_id = nil
@comment.save
end
def destroy
@comment = Comment.find(params[:parent_id])
@comment.destroy
respond_to do |format|
format.html { redirect_to comments_url }
end
authorize! :destroy, @comment
end
private
def comment_params
params.require(:comment).permit(:title, :content, :user_id, :image)
end
end
I've tried setting a custom route in the form, this gets the form to at least appear, however when you hit the submit button it returns 'No route matches [POST] "/boards/1/comments/new"'. If I got to the controller and then change the corresponding "get" to a "post" then it causes the form to just reappear after pressing submit and nothing is added to the database. I've also experimented with shallow nesting my routes as per my instructors advice but this didn't work.
Upvotes: 0
Views: 271
Reputation: 527
Your association between boards and comments must be:
board.rb
has_many :comments
comment.rb
belongs_to :user
routes.rb
resources :boards do
resources :comments, only: [:new, :edit, :destroy]
end
this will create a route
new_board_comment GET /boards/:board_id/comments/new(.:format) comments#new
edit_board_comment GET /boards/:board_id/comments/:id/edit(.:format) comments#edit
board_comment DELETE /boards/:board_id/comments/:id(.:format) comments#destroy
Upvotes: 1