jamby
jamby

Reputation: 606

Rails: acts_as_commentable_with_threading children's comment form not working

So I'm using the acts_as_commentable_with_threading for a comment system similar to Reddit.

So on the show page of an item, I have a form_for that has (items/show.html.haml):

  - if user_signed_in?
    %h5 Have something to say?
    = form_for([@item, @new_comment], remote: true) do |f|
      .form-group
        = f.text_area :body, class: "form-control", rows: "3"
        = f.hidden_field :user_id, value: current_user.id
      .form-group
        = f.submit "Submit", class: "btn btn-sm"

With a controller that does (items_controller.rb):

  def show
    @item = Item.find(params[:id])
    @comments = @item.comment_threads
    if user_signed_in?
      @new_comment = Comment.build_from(@item, current_user.id, "")
    end
  end

This will then have a create.js.erb that will append the newly made comment onto the page

$('#comments').append("<%= escape_javascript(render partial: 'comment', locals: { comment: @comment } ) %>");

if ("<%= @comment.body %>") {
    $("#comment_body").val('')
}

This by itself, works. I render each comment, and then inside the partial that each comment is rendered from, if they have any children, I render the child comments too.

Such as...:

    - if [email protected]?
      = render partial: 'comments/comment', collection: @item.root_comments, as: :comment

However each comment is able to have a reply, and those replies can have replies of their own (again, like Reddit). So when I attempt to do the same thing with the child replies, it gives me a 500 error.

= form_for([@item, @new_comment], remote: true, html: { class: "comment-reply", id: "replyto_#{comment.id}" }) do |f|
  .col-md-5
    .form-group
      = f.text_area :body, class: "form-control", rows: "3"
      = f.hidden_field :user_id, value: current_user.id
      = f.hidden_field :parent_id, value: comment.id
    .form-group
      = f.submit "Submit", class: "btn btn-sm"
  %div{style: "clear:both;"}

So my question is, how do I make a form_for for the child comments, and then (probably) create a new js.erb so it won't "append", but rather, rerender the parent comment (so that would in turn render the newly made child comment).

I think I may need to make a new create, so like a create_child, but then what does the form_for turn into?

Upvotes: 0

Views: 582

Answers (1)

jamby
jamby

Reputation: 606

Figured it out myself.

Basically inside the comments_controller.rb I had to find out if the new reply had a parent_id.

  def create
    @item = Item.find(params[:item_id])
    @all_comments = @item.comment_threads
    if (params[:comment].has_key?(:parent_id))
      @parent = Comment.find(params[:comment][:parent_id])
    end
    @comment = Comment.build_from(@item, current_user.id, params[:comment][:body])
    if @comment.save
      if @parent
        @comment.move_to_child_of(@parent)
      end
      respond_to do |format|
        format.js
      end
    else
      flash.now[:error] = "Comment was not submitted."
      redirect_to root_path
    end
  end

And then inside my create.js.erb I needed to find out if it also had a parent_id:

if ("<%= @comment.parent_id %>") {
    $('.comment_<%= @comment.parent_id %>').append("<%= escape_javascript(render partial: 'comment', locals: { comment: @comment } ) %>");

    $("#replyto_<%= @comment.parent_id %>").val('');
    $("#replyto_<%= @comment.parent_id %>").toggle();
}
else {
$('#comments').append("<%= escape_javascript(render partial: 'comment', locals: { comment: @comment } ) %>");

    if ("<%= @comment.body %>") {
        $("#comment_body").val('');
    }
}

This allows the child comments to be appended (via JavaScript) and for them to be put under the correct parent.

Upvotes: 2

Related Questions