Search code examples
ruby-on-railsruby-on-rails-4rails-routingcomments

@project.comments not displaying in my projects profile discussion page


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 %>

Solution

  • 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).