D
D
dexdev2013-12-11 12:48:45
Ruby on Rails
dexdev, 2013-12-11 12:48:45

How to make views for tree comments on rails 4?

Good day, the second day I'm trying to make tree-like comments ...
At the moment I'm at a dead end.
So, in essence, what has been done:
The comments table has been created, the migrations of which are registered in the gem
File models/comment.rb

class Comment < ActiveRecord::Base
  acts_as_commentable
  acts_as_nested_set :scope => [:commentable_id, :commentable_type]
  validates :body, :presence => true
  validates :user, :presence => true
  belongs_to :commentable, :polymorphic => true
  belongs_to :user
  # Helper class method that allows you to build a comment
  # by passing a commentable object, a user_id, and comment text
  # example in readme
  def self.build_from(obj, user_id, comment)
    new \
      :commentable => obj,
      :body        => comment,
      :user_id     => user_id
  end
  def has_children?
    self.children.any?
  end
  scope :find_comments_by_user, lambda { |user|
    where(:user_id => user.id).order('created_at DESC')
  }
  scope :find_comments_for_commentable, lambda { |commentable_str, commentable_id|
    where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
  }
  def self.find_commentable(commentable_str, commentable_id)
    commentable_str.constantize.find(commentable_id)
  end
end

FILE models/post.rb
class Post < ActiveRecord::Base
  acts_as_commentable
has_many :comments #не уверен что это нужно, потому что acts_as_commentable загрузил ассоциации
end

File controller/comments_controller.rb
class CommentsController < ApplicationController

  def create
    @post = Post.find(params[:post_id])
    @all_comments = @post.comment_threads
    if (params[:comment].has_key?(:parent_id))
      @parent = Comment.find(params[:comment][:parent_id])
    end
    @comment = Comment.build_from(@post, 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
end

File controller/posts_controller.rb
class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
    @comments = @post.comment_threads.order('created_at desc')
        @new_comment = Comment.build_from(@post, current_user.id, "")
    #@comments = @post.comment_threads
  end

File views/comments/_form.html.erb
<div class='comment-form'>
      <%= form_for([@post, @new_comment], remote: true, html: { class: "comment-reply", id: "replyto_#{comment.id}" }) do |f| %>
          <%= f.text_area :body, :rows => 3 %>
          <%= f.hidden_field :user_id, value: current_user.id %>
          <%= f.hidden_field :parent_id, value: comment.id %>
          <%= f.submit "Комментировать" %>
      <% end %>
</div>

File views/comments/create.js.erb
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('');
    }
}

Now it all works, now I can’t figure out how to write views for the comments themselves so that there are tree-like comments with display in posts/show.html.erb, and for the destroy action with destroy.js.erb
I am writing on rails 4.0.0.0
Ruby 2.0.0
Help me please.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
D
dexdev, 2013-12-11
@AdilA

As usual, everything is banal and you just
had to create a partial

<li>
  <p><%= comment.user.name %>: <%= comment.body %>
    </p>

  <p><%= "Replies (#{comment.children.size}): " if comment.has_children? %></p>
  <ol>
    <% comment.children.each do |child_comment| %>
        <li><p><%= child_comment.user.name %>: <%= child_comment.body %>
          </p>
        </li>
    <% end %>
    </ol>
    <%= form_for Comment.new, url: post_comments_path(@post) do |f| %>
    <%= f.hidden_field :parent_id, :value => comment.id %>
      <%= f.text_field :body %>
      <%= f.submit 'Replay' %>
  <% end %>
  </ol>

and write the correct render<%= render @post.root_comments %>

F
FanKiLL, 2013-12-11
@FanKiLL

<% @comments.each do |comment| %> #проходимся по комментам
    <%= comment.user.user_name%> # кто написал коммент
    <% if comment.has_children? %>
    	#сделать линк по которому ajax будут забиратся коменты для этой ветки?
        #или делать еще 1 do block и проходить по дочерним комментам.
  <% else %>
  <% end %>

CommentAs far as I understand, you have a method for this in your class .has_children?

F
FanKiLL, 2013-12-11
@FanKiLL

Does it find anything at all?
You pass parent_idin hiden field
Maybe so?

F
FanKiLL, 2013-12-11
@FanKiLL

<%= form_for([@post, @new_comment]) do |f| %>
For this, the [@post, @new_comment]rails create their own url, something like /posts/{post_id}/comments/{comment_id}
This is where this parrent id can be taken from.
Add this to application.html.erbthe very end
to see what parameters are being passed at all

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question