Commenti nidificati / filettati / rientrati in stile Reddit per Rails?
-
19-08-2019 - |
Domanda
Mi chiedo se qualcuno ha già creato un sistema per commenti thread (per mancanza di un termine migliore) in Rails o se ho bisogno di costruirlo da solo.
Nel caso in cui non sia chiaro, ciò a cui mi riferisco è un sistema di commenti come quello di Reddit che indentifica automaticamente le risposte in modo che appaiano come rami di un albero (preferibilmente con voto proprio come fa Reddit).
Se qualcuno potesse indicarmi il codice che lo fa, sarebbe molto apprezzato.
O forse esiste un progetto open source che include questa funzionalità.
Finora non sono stato in grado di trovarne uno su Rails.
Inoltre, sarebbe meglio chiedere questo su un forum Rails e, in caso affermativo, quale? (Sono nuovo su Rails)
Soluzione
L'uso del plug-in acts_as_tree
dovrebbe renderlo abbastanza facile da implementare. Installalo 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 si verifica in show.html.erb
quando chiama <%= render :partial => 'comments/comment', :object => Comment.find(params[:id]) %>
, questo farà sì che il parziale ritorni in modo ricorsivo tutti i commenti dei bambini. Se vuoi un limite alla profondità, puoi farlo nel parziale o nel modello.
Modifica
Questo ti lascerà con tutti i commenti con la stessa spaziatura nel codice HTML per ogni profondità. Se vuoi produrre HTML di facile lettura, usa render(...).gsub(/^/, "\t")
funzionerà in modo ricorsivo e producerà HTML ben rientrato.
L'ho combinato con il mio metodo in app/helpers/application_helper.rb
def indented_render(num, *args)
render(*args).gsub(/^/, "\t" * num)
end
Quindi ora puoi chiamare <%= indented_render 1, :partial => 'comments/comment', ... %>
Modifica
Risolto il problema con la chiusura del tag </h1>
mancante nell'esempio.
Altri suggerimenti
I collegamenti alla documentazione di ActsAsTree forniti da Hector e Samuel sembrano essere rotti. Puoi ottenere i documenti su
http://web.archive.org/web/20061011101510/http://wiki.rubyonrails.org/rails/pages/ActsAsTree
(Ho usato un pre-tag perché il collegamento continuava a essere visualizzato in modo errato per qualche motivo).
Esiste una gemma has_threaded_comments, non l'ha mai usata, ma sembra che faccia esattamente questo: https://github.com/aarongough/has_threaded_comments
Hai provato acts_as_tree
plugin sul tuo modello?
È un componente ActiveRecord ufficiale.