Pregunta

Me pregunto si alguien ya ha construido un sistema para comentarios enhebrados (por falta de un término mejor) en Rails o si necesito construirlo yo mismo.

En caso de que no esté claro, a lo que me refiero es a un sistema de comentarios como el de Reddit que sangra automáticamente las respuestas para que aparezcan como ramas de un árbol (preferiblemente con la votación como lo hace Reddit).

Si alguien pudiera señalarme un código que haga esto, sería muy apreciado.

O tal vez hay un proyecto de código abierto que incluye esta funcionalidad.

Hasta ahora no he podido encontrar uno en Rails.

Además, ¿sería mejor preguntar esto en un foro de Rails y, de ser así, cuál? (Soy nuevo en Rails)

¿Fue útil?

Solución

El uso del complemento acts_as_tree debería facilitar la implementación. Instálelo usando

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>

La magia ocurre en show.html.erb cuando llama a <%= render :partial => 'comments/comment', :object => Comment.find(params[:id]) %>, esto hará que el parcial haga recursivamente todos los comentarios de los niños. Si desea un límite en la profundidad, puede hacerlo en forma parcial o en el modelo.

Editar:
Esto te dejará con todos los comentarios con el mismo espacio en el HTML para cada profundidad. Si desea producir HTML fácil de leer, simplemente use render(...).gsub(/^/, "\t") esto funcionará recursivamente y producirá HTML con sangría agradable.

Lo combiné en mi propio método en app/helpers/application_helper.rb

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

Entonces ahora puedes llamar a <%= indented_render 1, :partial => 'comments/comment', ... %>

Editar:
Se corrigió la etiqueta de cierre </h1> faltante en el ejemplo.

Otros consejos

Los enlaces a la documentación de ActsAsTree, tal como los dieron Héctor y Samuel, parecen estar rotos. Puede obtener los documentos en

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

(Usé una etiqueta previa ya que el enlace seguía mostrándose incorrecto por alguna razón).

Hay una gema has_threaded_comments, nunca la usó, pero parece que hace exactamente esto: https://github.com/aarongough/has_threaded_comments

¿Intentó con el complemento acts_as_tree en su modelo? Es un componente oficial de ActiveRecord.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top