¿Comentarios anidados / roscados / sangrados al estilo Reddit para Rails?
-
19-08-2019 - |
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)
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.