Reddit-style nested/threaded/indented comments for Rails?

前端 未结 4 974
滥情空心
滥情空心 2020-12-22 17:49

I\'m wondering if someone has already built a system for threaded comments (for lack of a better term) in Rails or if I need to build it myself.

In case it\'s not c

相关标签:
4条回答
  • 2020-12-22 18:10

    Using the acts_as_tree plugin should make this fairly easy to implement. Install it using

    ruby script/plugin install acts_as_tree

    app/models/comment.rb

    class Comment < ActiveRecord::Base
      acts_as_tree :order => 'created_at'
    end
    

    db/migrate/20090121025349_create_comments.rb

    class CreateComments < ActiveRecord::Migration
      def self.up
        create_table :comments do |t|
          t.references :parent
          t.string :title
          t.text :content
          ...
          t.timestamps
        end
      end
    
      def self.down
        drop_table :comments
      end
    end
    

    app/views/comments/_comment.html.erb

    <div id="comment_<%= comment.id %>">
      <h1><%= comment.title %></h1>
      <%= comment.content %>
      <%= render :partial => 'comments/comment', :collection => comments.children %>
    </div>
    

    app/views/comments/show.html.erb

    <div id="comments">
      <%= render :partial => 'comments/comment', :object => Comment.find(params[:id]) %>
    </div>
    

    The magic happens in show.html.erb when it calls <%= render :partial => 'comments/comment', :object => Comment.find(params[:id]) %>, this will cause the partial to recursively render all children comments. If you want a limit to the depth, you can do it in the partial or in the model.

    Edit:
    This will leave you with all the comments with the same spacing in the HTML for every depth. If you want to produce easy to read HTML, just use render(...).gsub(/^/, "\t") this will work recursively as well producing nicely indented HTML.

    I combined it into my own method in app/helpers/application_helper.rb

    def indented_render(num, *args)
      render(*args).gsub(/^/, "\t" * num)
    end
    

    So now you can call <%= indented_render 1, :partial => 'comments/comment', ... %>

    Edit:
    Fixed missing closing </h1> tag in the example.

    0 讨论(0)
  • 2020-12-22 18:11

    The links to the ActsAsTree documentation as given by Hector and Samuel seem to be broken. You can get the docs at

     
    http://web.archive.org/web/20061011101510/http://wiki.rubyonrails.org/rails/pages/ActsAsTree
    

    (I used a pre tag as the linked kept displaying wrong for some reason).

    0 讨论(0)
  • 2020-12-22 18:24

    Did you tried acts_as_tree plugin on your model? It's a official ActiveRecord component.

    http://wiki.rubyonrails.org/rails/pages/ActsAsTree

    0 讨论(0)
  • 2020-12-22 18:25

    There is a has_threaded_comments gem, never used it, but it looks like it does exactly this: https://github.com/aarongough/has_threaded_comments

    0 讨论(0)
提交回复
热议问题