I'm trying to implement a commenting system using the 'closure-tree' gem and I am having some trouble getting comments to initially display on my project profile 'discussion' page.
I created an attribute on the comments model for project_id and it is not setting at all when i create the new comment from the project instance (project_id comes back as nil in the rails console). My question is:
1) Do i even need that project_id field if I have my routes and models/controllers setup as seen below? and also
2) if not (i will remove that attibute), what do i need to change to make sure the newly created comments are associated somehow with the project instance I added them from in order to get
<%= render @project.comments %>
to display all the project comments? I appreciate the help in advance.
My Models:
class Comment < ActiveRecord::Base
belongs_to :owner, :foreign_key=>'user_id', :class_name=>'User'
belongs_to :project
end
class Project < ActiveRecord::Base
belongs_to :owner, :foreign_key=>'user_id', :class_name=>'User'
has_many :comments
end
My ProjectsController:
def comments
@title = "Project Comments"
@project = Project.find(params[:id])
@comments = @project.comments
render 'show_project_discussion'
end
My CommentsController:
class CommentsController < ApplicationController
before_filter :authenticate_user!, only: [:create, :new, :edit, :update, :delete]
def index
@comments = Comment.all
end
def new
@project_id = params[:project_id]
@comment = Comment.new
end
def create
@project = Project.find(params[:project_id])
@comment = current_user.own_comments.build(comment_params)
if @comment.save
flash[:success] = 'Your comment was posted!'
redirect_to root_url
else
render 'new'
end
end
private
def comment_params
params.require(:comment).permit(:body, :project_id, :user_id)
end
end
Views/Projects/Show_Project_Discussion Partial:
<div class="container middle">
<!-- SideBar NEED TO REFACTOR TO A USER LAYOUT FILE -->
<div class="sidebar col-md-3">
<div class="sidebar-content">
<div class="sidebar-pad">
<%= render 'project_sidebar' %>
</div>
</div>
</div>
<div class="main-content col-md-9">
<div class="main-breadcrumb">
</div>
<div class="section_header">
<h3>Discussion</h3>
<p>Click the button below to start a new thread:</p>
<p>
<%= link_to "+ Add New Comment", new_project_comment_path(:project_id=> @project.id), :class => "btn btn-info col-md-4" %>
</p>
</div>
<%= render @project.comments %>
</div>
</div><!-- end Container -->
lastly My Routes.RB:
Rails.application.routes.draw do
devise_for :users
resources :users do
collection do
patch :update, as: :update
end
member do
get :following, as: :users_following
get :profile, as: :profile
end
end
resource :profile, only: [:show, :update]
resources :projects do
match '/settings'=>'projects#settings', :via=>:get, :as=>:settings
match '/invites'=>'projects#invites', :via=>:get, :as=>:invites
match '/invite_admin'=>'projects#invite_admin', :via=>:patch, :as=>:invite_admin
get :autocomplete_user_email, :on => :collection
end
resources :projects do
resources :comments, except: [:index]
member do
get :projectadmins
get :followers
get :tasks
get :comments
end
end
resources :tasks
resources :comments
end
I appreciate the help.
UPDATE:
added the project_sidebar partial to show how i pass the project_id:
<ul class="sidebar-menu">
<div class="sidebar-header">
<h4 class="head">Explore this Project</h4>
</div>
<li>
<h4>
<a href="<%= project_path(@project) %>">
Overview
</a>
</h4>
</li>
<li>
<h4>
<a href="<%= tasks_project_path(@project) %>">
Tasks
</a>
</h4>
</li>
<% if policy(@project).comments? %>
<li>
<h4>
<a href="<%= comments_project_path(@project) %>">
Discussion
</a>
</h4>
</li>
<% end %>
<ul>
And lastly views/comments/_form:
<%= form_for @comment, :html => {:multipart => true} do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :body %>
<%= f.text_area :body, class: 'form-control', required: true %>
<%= hidden_field_tag 'project_id', @project_id %>
<br clear="all">
<%= f.submit "Add your Comment", class: "btn btn btn-info" %>
<% end %>
You've used hidden_field_tag
, as a result params[:project_id]
is being set whereas your code is trying to use params[:comment][:project_id]
.
Either change the form to submit that parameter name instead and leave your controller alone or leave the form unchanged and update the controller (you would have to set the project_id on comment explicitly).