mercredi 14 octobre 2015

Ancestry Gem for Nested Comments with Rails causing undefined method error

I have been trying to fix an error associated with using the Ancestry gem for comments on my app for Rails 4. I used railscast episode 262 as a guide. However, unlike the episode, my comments model is a nested resource inside another model.Before I go further, I will supply the necessary code for reference. If you like to read the error right away, it is mentioned right after all the code snippets.

The Relevant Models:

class Comment < ActiveRecord::Base
  has_ancestry 
  belongs_to :user
  belongs_to :scoreboard
end



 class Scoreboard < ActiveRecord::Base 
  #scoreboard model is like an article page on which users can post comments
  belongs_to :user
  has_many :teams, dependent: :destroy
  has_many :comments, dependent: :destroy
  end

Relevant code in the route file:

resources :scoreboards do 
   resources :comments
   resources :teams, only: [:edit, :create, :destroy, :update]
end

The Scoreboards Controller Method for the page on which one can post comments:

def show
  @scoreboard = Scoreboard.find_by_id(params[:id])
  @team = @scoreboard.teams.build
  @comment = @scoreboard.comments.new
 end

The Comments Controller:

class CommentsController < ApplicationController

    def new
     @scoreboard = Scoreboard.find(params[:scoreboard_id])
     @comment = @scoreboard.comments.new(:parent_id => params[:parent_id])
    end


    def create
     @scoreboard = Scoreboard.find(params[:scoreboard_id])
     @comment = @scoreboard.comments.new comment_params
     if @comment.save
         redirect_to scoreboard_url(@comment.scoreboard_id) 
     else
       render 'new'
     end
    end

 private

     def comment_params
      params.require(:comment).permit(:body, :parent_id).merge(user_id: current_user.id)
     end

end

I will include the migration for the ancestry gem if any mistakes were made on that :

class AddAncestryToComments < ActiveRecord::Migration
  def change
    add_column :comments, :ancestry, :string
    add_index :comments, :ancestry
  end
end

The following code shows the view code:

Scoreboard#show View which is giving me the error in the last line:

<div class= "comment-section">
  <%= form_for [@scoreboard, @comment] do |f| %> 
   <%= render 'shared/error_messages', object: f.object %>
   <%= f.text_area :body, class: "comment-field" %>
   <%= f.hidden_field :parent_id %> #is it needed to include this here? because this form is for new comments not replies  
   <%= f.submit "Join the discussion...", class: " comment-button btn btn-primary" %>      
  <% end %>

<%= nested_comments @scoreboard.comments.reject(&:new_record?).arrange(:order => :created_at) %>
 </div>

The (comments partial)_comment.html.erb View:

<div class=" comment-div"> 
 <p> Posted by <%= link_to "#{comment.user.name}", comment.user %>
   <%= time_ago_in_words(comment.created_at) %> ago
 </p>
 <div class="comment-body"> 
  <%= comment.body %>
  <%= link_to "Reply", new_scoreboard_comment_path(@scoreboard, comment, :parent_id => comment) %> 
 </div>
</div>

The helper method to render comments:

def nested_comments(comments)
  comments.map do |comment, sub_comment| #the comments.map also gives me an error if I choose to render the comments without the .arrange ancestry method 
    render(comment) + content_tag(:div, nested_comments(sub_comment), class:  "nested_messages")
  end.join.html_safe
end

The new.html.erb for Comments which one is redirected to for the replies form submission:

<%= form_for [@scoreboard, @comment] do |f| %> 
        <%= render 'shared/error_messages', object: f.object %>
        <%= f.text_area :body, class: "comment-field" %>
        <%= f.hidden_field :parent_id %>   
        <%= f.submit "Join the discussion...", class: " comment-button btn btn-primary" %>               
<% end %>

Upon creating a scoreboard, I am redirected to the show page, where i get the following error:

undefined method `arrange' for []:Array

Even though the array of comments is empty, I get the same error if it wasnt. I have tried .subtree.arrange but that gives me the same error. Also, the ancestry documentation said that .arrange works on scoped classes only. I don't know what that means. I would appreciate some help on making the page work so the comments show properly ordered with the replies after their parent comments. If this is the wrong approach for threaded comments(replies and all), I would appreciate some guidance on what to research next.

1 commentaire:

  1. I must say, I thought this was a pretty interesting read when it comes to this topic. Liked the material. . . . .
    Tropic Diva

    RépondreSupprimer