Erstellung eines Forums von Anfang mit Ruby on Rails
() translation by (you can also view the original English article)
Heute werden wir ein einfaches Forum mit Ruby on Rails erstellen und uns mit den Grundlagen befassen, die Dinge wie Authentifizierung und fortgeschrittenere Datenbanktechniken abdecken.
Ruby on Rails
Wenn Sie mit Ruby on Rails nicht vertraut sind, handelt es sich um ein Webanwendungsframework, das mit der Programmiersprache Ruby erstellt wurde. Auf net.tuts+ wurden einige gute Tutorials zum Einstieg in Rails veröffentlicht. Eine kurze Übersicht finden Sie in meinem vorherigen Artikel.
Schritt 1 - Erstellen Sie die Rails-App



Um unsere Anwendung zu erstellen, verwenden wir den Befehl Rails, gefolgt vom Namen unseres Projekts. In diesem Fall handelt es sich um ein Forum. Der folgende Terminalbefehl wurde von mir verwendet. Stellen Sie außerdem sicher, dass Sie in das richtige Verzeichnis in Ihrem Terminal gewechselt haben.
1 |
rails forum |
Nach dem Ausführen des Befehls wird eine lange Textzeile mit allen gerade erstellten Dateien angezeigt. Jetzt möchten Sie in das gerade erstellte Verzeichnis wechseln.
Schritt 2 - Edelsteine installieren
Sie fragen sich wahrscheinlich, was ein Edelstein ist. Ein Gem ist ein in sich geschlossenes Paket zum Verteilen von Ruby-Programmen und -Bibliotheken. Sie sind sehr oft nützlich und erleichtern Ihnen das Leben. Wir werden einige Edelsteine für dieses Projekt verwenden, die unten aufgeführt sind. Stellen Sie außerdem sicher, dass Sie über die neueste Version von RubyGems und Ihren Edelsteinen verfügen, indem Sie Folgendes ausführen:
1 |
gem update --system |
(bei Bedarf mit Sudo)
1 |
gem update |
(bei Bedarf mit Sudo)
- nifty-generators: Ryan Bates 'erstaunliche nifty-generators werden für die Nifty-Authentifizierungs- und Nifty-Scaffold-Generatoren verwendet
- database: Stellen Sie sicher, dass Sie alle Juwelen haben, die Sie für die Schnittstelle mit der Datenbank benötigen, die Sie verwenden werden. Ich werde SQLite verwenden



Schritt 3 - Einrichten der Authentifizierung
Nachdem wir alle benötigten Edelsteine installiert haben, führen Sie Folgendes in Ihrem Terminal aus: (Stellen Sie sicher, dass Sie sich in den erstellten Verzeichnisschienen befinden.)
1 |
script/generate nifty_authentication |



Sie sollten sehen, wie Text wie oben vorbeifliegt. Öffnen Sie nun den Ordner in Ihrer bevorzugten IDE. Wir werden zuerst die Datei config/database.yml bearbeiten. Die Datei sollte so eingerichtet sein, dass sie das gewünschte Datenbanksystem verwendet. In diesem Fall verwende ich SQLite.
Stellen Sie sicher, dass alles ordnungsgemäß eingerichtet ist, und führen Sie dann den folgenden Befehl aus, um Änderungen in unsere Datenbank zu migrieren:
1 |
rake db:migrate |



Schritt 4 - Die Anwendungsstruktur
Nein, dieser Teil wird sich nicht mit dem Anwendungslayout im Hinblick auf das Gesamtdesign befassen. Wir werden in Kürze daran arbeiten. In diesem Abschnitt wird beschrieben, wie die Anwendung erstellt wird. Einer der größten Vorteile von Ruby on Rails ist die Fülle der verfügbaren Generatoren. Das einzige Problem, das manche Leute vermissen, ist, dass Sie Ihre Anwendung planen müssen, damit diese Generatoren wirklich die Extrameile gehen.
Im Folgenden wird beschrieben, wie die Modelle in der Datenbank organisiert und in Beziehung gesetzt werden.
- Forum: Ein Forum ist die oberste Ebene. Grundsätzlich eine Gruppe von Themen, die sich aufeinander beziehen.
- Topic: Ein Theme, auch Thread genannt, betrifft ein bestimmtes Theme.
- Post: Ein Beitrag gehört zu einem Theme und ist eine Nachricht eines bestimmten Benutzers.
Wir werden also ein raffiniertes Scaffold verwenden, um drei Modelle zu generieren, eines für jedes der oben aufgeführten Teile. Als erstes werden wir das Scaffold verwenden, um unser Forum zu erstellen. Führen Sie dazu den folgenden Befehl aus:
1 |
script/generate nifty_scaffold forum name:string description:text |



Danach werden wir ein Scaffold für das Theme erstellen:
1 |
script/generate nifty_scaffold topic name:string last_poster_id:integer last_post_at:datetime |



Jetzt werden wir den Beitrag gerüsten:
1 |
script/generate nifty_scaffold post content:text |



Migrieren Sie dann die Datenbank:
1 |
rake db:migrate |



Schritt 5 - Erstellen des Layouts
Jetzt werden wir tatsächlich am ersten Teil des Gesamtbildes der Website arbeiten. Aufgrund der Tatsache, dass wir nifty_scaffold verwenden, werden wir auch nifty_layout verwenden, um einige der grundlegenden Layouts zu generieren, die wir ändern werden. Führen Sie Folgendes aus, um nifty_layout zu verwenden:
1 |
script/generate nifty_layout |



Dies war ein sehr schneller Schritt, um dies vorerst zum Laufen zu bringen. Wir werden später darauf zurückkommen.
Schritt 6 - Einrichten der Zuordnungen
Also werden wir Assoziationen in unseren Modellen schaffen. Assoziationen sind Möglichkeiten, Modelle zu verknüpfen. Öffnen wir zuerst unsere app/models/forum.rb und Sie sollten sehen:
1 |
# app/models/forum.rb
|
2 |
class Forum < ActiveRecord::Base |
3 |
end
|
Jetzt werden wir etwas Code hinzufügen und es sollte wie folgt aussehen, und ich werde es in einer Minute erklären.
1 |
# app/models/forum.rb
|
2 |
class Forum < ActiveRecord::Base |
3 |
has_many :topics, :dependent => :destroy |
4 |
end
|
Der Code has_many bedeutet genau, wie es sich anhört; es hat viele und dann verweisen wir auf unser Modell Theme. Sie fragen sich vielleicht, warum es funktioniert, wenn Sie ein 's' hinzufügen, und das ist die ActiveRecord-Konvention. Das :dependent => :destroy bedeutet, dass beim Löschen des Forums auch alle seine Themen behandelt werden. Jetzt öffnen wir unsere App/models/topic.rb und bearbeiten sie wie folgt:
1 |
# app/models/topic.rb
|
2 |
class Topic < ActiveRecord::Base |
3 |
belongs_to :forum |
4 |
has_many :posts, :dependent => :destroy |
5 |
end
|
Auch dies ist einfacher Text. Es heißt, ein Theme gehört zu einem Forum und hat viele Beiträge. Wir verwenden auch :dependent => :destroy hier zerstören, um alle untergeordneten Beiträge zu löschen. Öffnen Sie nun app/models/post.rb und bearbeiten Sie es wie folgt:
1 |
# app/models/post.rb
|
2 |
class Post < ActiveRecord::Base |
3 |
belongs_to :topic |
4 |
end
|
Jetzt werden wir drei Migrationen erstellen, die unsere Fremdschlüssel zu unserer Datenbank hinzufügen. Wenn Sie dies beim Gerüstbau gewollt hätten, hätten Sie es tun können, obwohl die Art und Weise, wie wir vorgehen, Ihnen auch eine andere Rails-Technik beibringt, sodass ich der Meinung war, dass dieser Weg besser wäre. Führen Sie also unsere erste Migration aus:
1 |
script/generate migration add_foreign_to_topics forum_id:integer |
Dieser Befehl generiert eine Migration mit dem Namen add_foreign_to_topics, erkennt automatisch, dass wir das Themenmodell ändern möchten, und übergibt dann das, was wir hinzufügen möchten. In diesem Fall fügen wir eine Spalte mit dem Namen forum_id hinzu, die ein ganzzahliger Typ ist. So erstellen Sie die Migration zum Hinzufügen unseres Fremdschlüssels forum_id zu unserem Themenmodell. Der nächste Befehl erstellt dann die Migration
1 |
script/generate migration add_foreign_to_posts topic_id:integer |



Jetzt können wir die Datenbank erneut migrieren mit:
1 |
rake db:migrate |
Schritt 7 - Erste Schritte auf der Startseite
Jetzt können wir mit dem Aufbau der Funktionalität der Site beginnen. Öffnen Sie also zuerst config/route.rb und fügen Sie die folgende Zeile neben den auskommentierten Zeilen hinzu:
1 |
# config/routes.rb
|
2 |
map.root :controller => "forums" |
Speichern Sie die Datei und löschen oder benennen Sie die Datei public/index.html um. Jetzt möchten wir die Ansicht für die Indexdatei in app/views/forums/index.html.erb öffnen und wie folgt bearbeiten:
1 |
# app/views/forums/index.html.erb |
2 |
<% title "Forums" %> |
3 |
|
4 |
<table>
|
5 |
<tr>
|
6 |
<th width="70%">Forum</th> |
7 |
<th width="30%">Last Post</th> |
8 |
</tr>
|
9 |
<% for forum in @forums %> |
10 |
<tr>
|
11 |
<td><h4><%= link_to h(forum.name), forum_path(forum.id) %></h4> |
12 |
<small><%= forum.topics.count %> topics</small><br /> |
13 |
<%=h forum.description %></td> |
14 |
<td class="right"></td> |
15 |
<td><%= link_to "Show", forum %></td> |
16 |
<td><%= link_to "Edit", edit_forum_path(forum) %></td> |
17 |
<td><%= link_to "Destroy", forum, :confirm => 'Are you sure?', :method => :delete %></td> |
18 |
</tr>
|
19 |
<% end %> |
20 |
</table>
|
21 |
|
22 |
<p><%= link_to "New Forum", new_forum_path %></p> |
Ich habe den Tabellenkopftext in den Text geändert, den wir in jede Zelle einfügen werden, sowie die Breite der Zellen. Es gibt noch Änderungen, die wir später vornehmen werden. Öffnen Sie nun die Datei application.css im Verzeichnis public/stylesheets. Ich habe die CSS-Reset- und Typografiedateien 960.gs oben im Stylesheet hinzugefügt. Dann habe ich die folgenden Stile am Ende der Datei hinzugefügt:
1 |
# public/stylesheets/application.css |
2 |
table tr th {background:#222; color:#fff; padding:0; border:#111 solid 1px;} |
3 |
table tr td {border:1px #ccc solid; padding:5px;} |
4 |
table tr td.right {background: #eee;} |
5 |
table tr td h4 {margin:0; padding:0; font-weight:normal;} |
Wenn Sie nun den Server mit Skript/Server starten möchten, sollten Sie Folgendes sehen: (S. Ich habe der Datenbank einen Datensatz hinzugefügt, um nur ein Beispiel zu geben.)
Nachdem wir uns um unsere Indexaktion gekümmert haben, können wir an unserer Showaktion für das Forum arbeiten. Diese Datei befindet sich in app/views/forums/show.html.erb. Wir werden den größten Teil des Codes aus unserer Indexaktion in diesen kopieren, und der endgültige Code ist unten:
1 |
# app/views/forums/show.html.erb |
2 |
<% title @forum.name %> |
3 |
|
4 |
<table>
|
5 |
<tr>
|
6 |
<th width="60%">Topic Title</th> |
7 |
<th width="10%">Replies</th> |
8 |
<th width="30%">Last Post</th> |
9 |
</tr>
|
10 |
<% for topic in @forum.topics %> |
11 |
<tr>
|
12 |
<td><%= link_to h(topic.name), topic_path(topic.id) %> |
13 |
<td><%= topic.posts - 1 %></td> |
14 |
<td class="right"></td> |
15 |
<td><%= link_to "Show", topic %></td> |
16 |
<td><%= link_to "Edit", edit_topic_path(topic) %></td> |
17 |
<td><%= link_to "Destroy", topic, :confirm => 'Are you sure?', :method => :delete %></td> |
18 |
</tr>
|
19 |
<% end %> |
20 |
</table>
|
21 |
|
22 |
<p><%= link_to "New Topic", "/topics/new?forum=#{@forum.id}" %></p> |
Ich weiß, dass ich den Code in den beiden obigen Ansichten nicht erklärt habe, daher erkläre ich ihn jetzt. In der ersten Zeile legen wir den Titel für die Seite fest. Anschließend erstellen wir eine Tabelle und richten die Tabellenüberschriften ein. Danach starten wir eine Schleife für jedes Element in den Themen unseres Forums und verwenden die lokale Variable des Themes. Wir erstellen dann einen Link für jedes Theme, dann die Anzahl der Beiträge minus 1, um den ursprünglichen Beitrag zu berücksichtigen. Dann haben wir ein zusätzliches td, das wir später verwenden werden, und dann die Admin-Links, um die wir uns später auch kümmern werden.
Schritt 8 - Arbeiten an den Formularen
Nun haben wir das Grundlayout für unser Frontend. Wir müssen an dem Formular arbeiten, um ein Theme zu erstellen. Sie sollten etwas haben, das wie folgt aussieht:



Nun, das funktioniert derzeit nicht für das, was wir tun wollen. Wir erstellen derzeit keinen Beitrag, wenn wir ein Theme erstellen, und wir gewähren Benutzern derzeit Zugriff auf Optionen, die sie nicht sehen sollten. Öffnen Sie also app/views/topic/_form.html.erb. Ihre aktuelle Datei sollte so aussehen:
1 |
# app/views/topics/_form.html.erb |
2 |
<% form_for @topic do |f| %> |
3 |
<%= f.error_messages %> |
4 |
<p>
|
5 |
<%= f.label :name %><br /> |
6 |
<%= f.text_field :name %> |
7 |
</p>
|
8 |
<p>
|
9 |
<%= f.label :last_poster_id %><br /> |
10 |
<%= f.text_field :last_poster_id %> |
11 |
</p>
|
12 |
<p>
|
13 |
<%= f.label :last_post_at %><br /> |
14 |
<%= f.datetime_select :last_post_at %> |
15 |
</p>
|
16 |
<p><%= f.submit "Submit" %></p> |
17 |
<% end %> |
Also werden wir die Teile mit der last_poster_id und last_post_at löschen. Wir werden auch einen Textbereich für den Beitrag und einige versteckte Felder hinzufügen. Sie werden sehen, dass ich die Rails-Helfer nicht benutze, und das ist nur meine persönliche Präferenz. Ihr endgültiges Formular sollte folgendermaßen aussehen:
1 |
# app/views/topics/_form.html.erb |
2 |
<% form_for @topic do |f| %> |
3 |
<%= f.error_messages %> |
4 |
<% if params[:forum] %><input type="hidden" id="topic_forum_id" name="topic[forum_id]" value="<%= params[:forum] %>" /><% end %> |
5 |
<p>
|
6 |
<%= f.label :name %><br /> |
7 |
<%= f.text_field :name %> |
8 |
</p>
|
9 |
<p>
|
10 |
<textarea name="post[content]" cols="80" rows="20"><%= @post.content %></textarea> |
11 |
</p>
|
12 |
<p><%= f.submit "Create" %></p> |
13 |
<% end %> |
Und in Ihrem Browser sollte es so aussehen:
Wir werden diese in unserem Controller speichern. Speichern Sie also die Ansicht, öffnen Sie die Datei app/controller/topic_controller.rb und suchen Sie die Aktion zum Erstellen. Bearbeiten Sie es so, dass es aussieht wie:
1 |
# app/controllers/topic_controller.rb
|
2 |
def create |
3 |
@topic = Topic.new(params[:topic]) |
4 |
if @topic.save |
5 |
@topic = Topic.new(:name => params[:topic][:name], :last_poster_id => current_user.id, :last_post_at => Time.now, :forum_id => params[:topic][:forum_id]) |
6 |
|
7 |
if @post.save |
8 |
flash[:notice] = "Successfully created topic." |
9 |
redirect_to "/forums/#{@topic.forum_id}" |
10 |
else
|
11 |
redirect :action => 'new' |
12 |
end
|
13 |
else
|
14 |
render :action => 'new' |
15 |
end
|
16 |
end
|
Wir haben Code hinzugefügt, um das Erstellen des Beitrags zum Theme zu handhaben. Um dies zu vereinfachen, werden wir die Indexaktion in unserem Controller löschen. Wir werden auch das Update aktualisieren und Aktionen zerstören, um die Umleitung ordnungsgemäß durchzuführen. Ändern Sie daher redirect_to für diese beiden Aktionen in:
1 |
redirect_to "/forums/#{@topic.forum_id}" |
Öffnen Sie nun app/controller/posts_controller.rb, löschen Sie den Index und zeigen Sie Aktionen an.
Schritt 9 - Einrichten weiterer Zuordnungen
Wenn Sie bemerkt haben, dass ich oben zwei Assoziationen übersprungen habe, begrüße ich Sie, dass Sie es bemerkt haben. Die Assoziationen, die wir übersprungen haben, bestanden zwischen Benutzern und ihren Posts und Themen. Dazu erstellen Sie zunächst zwei Migrationen und migrieren die Änderungen in die Datenbank:
1 |
script/generate migration add_user_to_posts user_id:integer |
2 |
script/generate migration add_user_to_topics user_id:integer |
3 |
rake db:migrate |
Um ActiveRecord über diese Zuordnungen zu informieren, öffnen Sie app/models/user.rb und fügen Sie die folgenden Zeilen unter before_save hinzu.
1 |
# app/models/user.rb
|
2 |
has_many :posts |
3 |
has_many :topics |
Öffnen Sie nun sowohl app/models/post.rb als auch app/models/topic.rb und fügen Sie die folgenden Zeilen hinzu:
1 |
# app/models/post.rb & app/models/topic.rb
|
2 |
belongs_to :user |
Jetzt haben wir die zusätzlichen Assoziationen, um fortzufahren.
Schritt 10 - Polieren der Forenliste
Nachdem wir nun die Grundlagen haben, werden wir fortfahren und die Forenliste aufpolieren, nachdem wir fortfahren und die Themenliste aufpolieren werden.
Öffnen wir zuerst app/models/forum.rb. Wir werden eine neue Methode hinzufügen, mit der wir den neuesten Beitrag in einem Forum finden können. Die Methode, die wir hinzufügen werden, ist unten:
1 |
# app/models/forum.rb
|
2 |
def most_recent_post |
3 |
topic = Topic.first(:order => 'last_post_at DESC', :conditions => ['forum_id = ?', self.id]) |
4 |
return topic |
5 |
end
|
Diese Methode findet das erste Theme, das eine Forum-ID hat, unabhängig von der ID des Forums, für das wir diese Methode aufgerufen haben, sortiert sie dann nach Datum und gibt den Wert zurück.
Öffnen Sie also die App/views/forums/index.html.erb und suchen Sie die Tabellenzelle in der Schleife, die eine Rechtsklasse hat. Wir werden es wie folgt ändern:
1 |
# app/views/forums/index.html.erb |
2 |
<td class="right"><% if forum.most_recent_post %><%= distance_of_time_in_words_to_now forum.most_recent_post.last_post_at %> ago<% else %>no posts<% end %></td> |
Dieser Code kann verwirrend aussehen, daher werde ich ihn durchgehen. Zuerst verweisen wir auf die Methode, die wir unserem Modell hinzugefügt haben, und prüfen, ob ein Datensatz zurückgegeben wurde, da wir möglicherweise ein Forum ohne Themen haben. Wenn wir einen Datensatz haben, verwenden wir als Nächstes die Datumshilfe, die Rails bereitstellt, um die Zeit in lesbaren Text zu analysieren. Wenn wir keinen Datensatz zurückgegeben haben, geben wir "keine Beiträge" aus. Ihre Seite sollte folgendermaßen aussehen:
Nachdem wir das Datum hinzugefügt haben, werden wir den Link zu dem Benutzer hinzufügen, der gepostet hat. Ändern Sie in der Ansicht diese Tabellenzelle so, dass sie wie folgt aussieht:
1 |
# app/views/forums/index.html.erb |
2 |
<td class="right"><% if forum.most_recent_post %> |
3 |
<%= distance_of_time_in_words_to_now forum.most_recent_post.last_post_at %> ago by |
4 |
<%= link_to forum.most_recent_post.user.username, "/users/#{forum.most_recent_post.last_poster_id}" %> |
5 |
<% else %>no posts<% end %> |
6 |
</td>
|
Ihre Seite sollte jetzt so aussehen:
Schritt 11 - Polieren Sie die Themenliste
Nun kehren wir zu unserer Datei app/views/forums/show.html.erb zurück. Der Titel dieses Schritts kann etwas verwirrend sein, da wir die Show-Aktion des Forums bearbeiten, aber tatsächlich an der Themenliste arbeiten. Nachdem Sie die Datei geöffnet haben, suchen Sie die Tabellenzelle im Look mit der Klasse 'right' erneut. Wir werden denselben Datums-Helfer verwenden und unser Code sieht folgendermaßen aus:
1 |
# app/views/forums/show.html.erb |
2 |
<td class="right"><%= distance_of_time_in_words_to_now topic.last_post_at %> ago by <%= link_to topic.user.username, "/users/#{topic.last_poster_id}" %></td> |
Wenn Sie nun Ihren Browser öffnen, sollten Sie Folgendes sehen:
Schritt 12 - Arbeiten an der Themenansicht
Nachdem wir nun alles in den Forum- und Themenlisten aussortiert haben, werden wir an der dritten Hauptansicht arbeiten. Öffnen Sie die App/views/topic/show.html.erb und bearbeiten Sie sie so, dass sie eher so aussieht:
1 |
# app/views/topics/show.html.erb |
2 |
<% title @topic.name %> |
3 |
|
4 |
<% for post in @topic.posts %> |
5 |
<div class="post"> |
6 |
<span class="left"><%= post.user.username %><br /><%= link_to "Delete", post, :confirm => 'Are you sute?', :method => :delete%></span> |
7 |
<span class="right"><%= post.content %></span> |
8 |
</div>
|
9 |
<% end %> |
10 |
|
11 |
<p>
|
12 |
<%= link_to "Edit", edit_topic_path(@topic) %> | |
13 |
<%= link_to "Destroy Topic", @topic, :confirm => 'Are you sure?', :method => :delete %> | |
14 |
<%= link_to "View All", topics_path %> |
15 |
</p>
|
Fügen wir noch etwas Styling hinzu:
1 |
# public/stylesheets/application.css |
2 |
.post {width:100%; display:table;} |
3 |
.post span {padding:5px; border:3px solid #eee; margin:0;} |
4 |
.post span.left {width:150px; background:#eee; border:3px solid #eee; display:table-cell;} |
5 |
.post span.right { border:3px solid #eee; display:table-cell;} |
Und jetzt sieht das Anzeigen eines Themes folgendermaßen aus:
Schritt 13 - Benutzeraktion anzeigen
Wenn ein Benutzername angeklickt wird, möchten wir dessen Profil anzeigen, richtig? Öffnen Sie dazu die App/controller/users_controller.rb und die folgende Show-Aktion:
1 |
# app/controllers/users_controller.rb
|
2 |
def show |
3 |
@user = User.find(params[:id]) |
4 |
end
|
Das ist alles, was wir für diese Aktion in unserem Controller benötigen. Erstellen Sie nun eine Datei mit dem Namen show.html.erb in app/views/users und platzieren Sie Folgendes darin:
1 |
# app/views/users/show.html.erb |
2 |
<% title 'user: ' + @user.username %> |
3 |
<div id="topics"> |
4 |
<strong>topics</strong> |
5 |
<% @user.topics.each do |topic| %> |
6 |
<%= link_to topic.name, topic_url(topic.forum.id) %> |
7 |
<% end %> |
8 |
</div>
|
Diese einfache Menge an Code zeigt die Themen des Benutzers an. Nein, hier gibt es keine Begrenzung, daher würden wir technisch alle Themen dieses Benutzers anzeigen. Die idealste Lösung wäre, Methoden zu erstellen, um dies in unserem Benutzermodell zu handhaben, aber das werde ich hier nicht tun.
Schritt 14 - Arbeiten mit Posts
Nachdem wir fast fertig sind, müssen wir an den Funktionen arbeiten, um einen Beitrag zu bearbeiten. Öffnen wir zunächst app/controller/topic_controller.rb und unsere Ansicht für die Show-Aktion. Zuerst werden wir auf dem Controller die Bearbeitungs- und Aktualisierungsfunktion löschen. Sie fragen sich vielleicht warum und der Grund ist, dass wir einem Benutzer nicht erlauben werden, das Theme zu bearbeiten, sondern Beiträge. Ja, dies ermöglicht es einem Benutzer nicht, den Titel eines Themes zu ändern. Dies ist jedoch besser, als die zusätzliche Logik zu schreiben, die zum Bearbeiten eines Themes erforderlich ist. Löschen Sie also diese Aktionen, und Sie können auch die entsprechenden Ansichten löschen.
Öffnen Sie nun die Datei app/views/topic/show.html.erb. Löschen Sie zunächst im Absatz-Tag unten den Link Bearbeiten, den ersten in der Liste. Gehen Sie dann zur Schleife und vor dem Link zum Löschen des Beitrags fügen wir einen Link zum Bearbeiten des Beitrags hinzu. Die Ansicht, wenn wir fertig sind, sollte folgendermaßen aussehen:
1 |
# app/views/topics/show.html.erb |
2 |
<% title @topic.name %> |
3 |
|
4 |
<% for post in @topic.posts %> |
5 |
<div class="post"> |
6 |
<span class="left"><%= link_to post.user.username, user_url(post.user) %><br /><%= link_to "Edit", edit_post_path(post) %><br /><%= link_to "Delete", post, :confirm => 'Are you sute?', :method => :delete %></span> |
7 |
<span class="right"><%= post.content %></span> |
8 |
</div>
|
9 |
<% end %> |
10 |
|
11 |
<p>
|
12 |
<%= link_to "Reply", "#{new_post_path}?topic=#{@topic.id}" %> | |
13 |
<%= link_to "Destroy Topic", @topic, :confirm => 'Are you sure?', :method => :delete %> | |
14 |
<%= link_to "View All", forum_path(@topic.forum_id) %> |
15 |
</p>
|
Wir haben auch einen Antwortlink für Funktionen hinzugefügt, die wir in einer Minute hinzufügen werden. Wenn Sie jetzt auf den Link klicken, um ihn zu bearbeiten, sollte er funktionieren. Wenn Sie dann versuchen, den Beitrag zu ändern, gibt Rails einen Fehler aus. Nun, wir möchten nicht, dass es umgeleitet wird, wo es sich gerade befindet. Öffnen Sie also app/controller/posts_controller.rb, scrollen Sie nach unten zur Aktion "Erstellen" und suchen Sie die Zeile "redirect_to @post". Wir werden die Zeile ändern, damit die endgültige Aktion wie folgt aussieht:
1 |
# app/controllers/posts_controller.rb
|
2 |
def create |
3 |
@post = Post.new(:content => params[:post][:content], :topic_id => params[:post][:topic_id], :user_id => current_user.id) |
4 |
if @post.save |
5 |
flash[:notice] = "Successfully created post." |
6 |
redirect_to "/topics/#{@post.topic_id}" |
7 |
else
|
8 |
render :action => 'new' |
9 |
end
|
10 |
end
|
Dieser Code leitet uns jetzt zur Show-Aktion für die Forum-ID des Beitrags weiter. Wir haben jedoch nur ein Problem: Die Erstellungsaktion wird nicht an die topic_id in der Ansicht übergeben. Öffnen Sie daher app/views/posts/_form.html.erb und fügen Sie die folgende Zeile unter den Fehlermeldungen hinzu.
1 |
# app/views/posts/_form.html.erb |
2 |
<% if params[:topic] %><input type="hidden" id="topic_forum_id" name="post[topic_id]" value="<%= params[:topic] %>" /><% end %> |
Nun, da wir auch das Theme aktualisieren müssen, haben wir einen neuen Beitrag. Um dies zu tun, werden wir die Erstellungsaktion erneut so ändern, dass sie wie folgt aussieht:
1 |
# app/controllers/posts_controller.rb
|
2 |
def create |
3 |
@post = Post.new(:content => params[:post][:content], :topic_id => params[:post][:topic_id], :user_id => current_user.id) |
4 |
if @post.save |
5 |
@topic = Topic.find(@post.topic_id) |
6 |
@topic.update_attributes(:last_poster_id => current_user.id, :last_post_at => Time.now) |
7 |
flash[:notice] = "Successfully created post." |
8 |
redirect_to "/topics/#{@post.topic_id}" |
9 |
else
|
10 |
render :action => 'new' |
11 |
end
|
12 |
end
|
Nachdem der Beitrag gespeichert wurde, haben wir die topic_id verwendet, um unser Theme zu finden, und dann zwei Spalten in unserer Datenbank aktualisiert. Kopieren Sie die beiden Zeilen, die wir in unserer Aktualisierungsaktion an derselben Stelle hinzugefügt haben, wie folgt:
1 |
# app/controllers/posts_controller.rb
|
2 |
def update |
3 |
@post = Post.find(params[:id]) |
4 |
if @post.update_attributes(params[:post]) |
5 |
@topic = Topic.find(@post.topic_id) |
6 |
@topic.update_attributes(:last_poster_id => current_user.id, :last_post_at => Time.now) |
7 |
flash[:notice] = "Successfully updated post." |
8 |
redirect_to @post |
9 |
else
|
10 |
render :action => 'edit' |
11 |
end
|
12 |
end
|
Wir haben auch die Umleitung für diese so geändert, dass sie der Aktion zum Erstellen entspricht. Gehen Sie nun zur Zerstörungsaktion und ändern Sie die Umleitung in:
1 |
redirect_to forums_url |
Schritt 15 - Die letzten Berührungen im Forum vornehmen
Jetzt müssen wir in unseren Ansichten schnell nach Links suchen, die unnötig sind oder nicht mehr funktionieren. Öffnen Sie zuerst die Show-Aktion für die Foren. Öffnen Sie also app/views/forums/show.html.erb und löschen Sie die Show und bearbeiten Sie die Links, sodass die Ansicht wie folgt aussieht:
1 |
# app/views/forums/show.html.erb |
2 |
<% title @forum.name %> |
3 |
|
4 |
<table>
|
5 |
<tr>
|
6 |
<th width="60%">Topic Title</th> |
7 |
<th width="10%">Replies</th> |
8 |
<th width="30%">Last Post</th> |
9 |
</tr>
|
10 |
<% for topic in @forum.topics %> |
11 |
<tr>
|
12 |
<td><%= link_to h(topic.name), topic_path(topic.id) %> |
13 |
<td><%= topic.posts.count - 1%></td> |
14 |
<td class="right"><%= distance_of_time_in_words_to_now topic.last_post_at %> ago by <%= link_to topic.user.username, "/users/#{topic.last_poster_id}" %></td> |
15 |
<td><%= link_to "Destroy", topic, :confirm => 'Are you sure?', :method => :delete %></td> |
16 |
</tr>
|
17 |
<% end %> |
18 |
</table>
|
19 |
|
20 |
<p><%= link_to "New Topic", "/topics/new?forum=#{@forum.id}" %></p> |
Wir müssen auch die Methode zur Themenerstellung aktualisieren, damit sie die Benutzer-ID unseres aktuellen Benutzers hinzufügt. Öffnen Sie daher app/controller/topic_controller.rb und ändern Sie die Zeile Topic.new in:
1 |
# app/controllers/topics_controller.rb
|
2 |
@topic = Topic.new(:name => params[:topic][:name], :last_poster_id => current_user.id, :last_post_at => Time.now, :forum_id => params[:topic][:forum_id], :user_id => current_user.id) |
Wir müssen auch die Datei app/views/forums/index.html.erb bereinigen. Öffnen Sie sie und löschen Sie den Show-Link, damit die Datei wie folgt aussieht:
1 |
# app/views/forums/index.html.erb |
2 |
<% title "Forums" %> |
3 |
|
4 |
<table>
|
5 |
<tr>
|
6 |
<th width="70%">Forum</th> |
7 |
<th width="30%">Last Post</th> |
8 |
</tr>
|
9 |
<% for forum in @forums %> |
10 |
<tr>
|
11 |
<td><h4><%= link_to h(forum.name), forum_path(forum.id) %></h4> |
12 |
<small><%= forum.topics.count %> topics</small><br /> |
13 |
<%=h forum.description %></td> |
14 |
<td class="right"><% if forum.most_recent_post %><%= distance_of_time_in_words_to_now forum.most_recent_post.last_post_at %> ago by <%= link_to forum.most_recent_post.user.username, "/users/#{forum.most_recent_post.last_poster_id}" %><% else %>no posts<% end %></td> |
15 |
<td><%= link_to "Edit", edit_forum_path(forum) %></td> |
16 |
<td><%= link_to "Destroy", forum, :confirm => 'Are you sure?', :method => :delete %></td> |
17 |
</tr>
|
18 |
<% end %> |
19 |
</table>
|
20 |
|
21 |
<p><%= link_to "New Forum", new_forum_path %></p> |
Schritt 16 - Verwaltungsfunktionen
Derzeit kann jeder Benutzer alles bearbeiten, löschen und erstellen, was er möchte. Also werden wir unseren Anwendungshelfer in app/helpers/application_helper.rb öffnen. Wir werden einige zusätzliche Methoden hinzufügen, um mit der Authentifizierung und den Benutzerebenen umzugehen. Fügen Sie vor dem Tag 'end' die folgenden Methoden hinzu:
1 |
# app/helpers/application_helper.rb
|
2 |
def admin? |
3 |
if current_user.permission_level == 1 || current_user.id == 1 |
4 |
return true |
5 |
else
|
6 |
return false |
7 |
end
|
8 |
end
|
9 |
|
10 |
def owner?(id) |
11 |
if current_user.id == id |
12 |
return true |
13 |
else
|
14 |
return false |
15 |
end
|
16 |
end
|
17 |
|
18 |
def admin_or_owner?(id) |
19 |
if (admin? || owner?(id)) |
20 |
return true |
21 |
else
|
22 |
return false |
23 |
end
|
24 |
end
|
Mit diesen Methoden können wir herausfinden, ob ein Benutzer ein Administrator und ein Eigentümer ist, indem wir die Benutzer-ID des gesuchten und eines, der beide behandelt, übergeben. Die Methodenprüfung für einen Administrator ermöglicht es dem ersten Benutzer auch, automatisch Administrator zu sein. Also werden wir zuerst die Datei index.html.erb des Forums öffnen. Wir werden jetzt zusätzlichen Code hinzufügen, um das Erstellen, Bearbeiten und Zerstören von Forum-Links für alle außer Administratoren zu verbergen. Wir werden jeden dieser Links mit <% if admin? %> und <% end%>. Der endgültige Code sieht folgendermaßen aus:
1 |
# app/views/forums/index.html.erb |
2 |
<% title "Forums" %> |
3 |
|
4 |
<table>
|
5 |
<tr>
|
6 |
<th width="70%">Forum</th> |
7 |
<th width="30%">Last Post</th> |
8 |
</tr>
|
9 |
<% for forum in @forums %> |
10 |
<tr>
|
11 |
<td><h4><%= link_to h(forum.name), forum_path(forum.id) %></h4> |
12 |
<small><%= forum.topics.count %> topics</small><br /> |
13 |
<%=h forum.description %></td> |
14 |
<td class="right"><% if forum.most_recent_post %><%= distance_of_time_in_words_to_now forum.most_recent_post.last_post_at %> ago by <%= link_to forum.most_recent_post.user.username, "/users/#{forum.most_recent_post.last_poster_id}" %><% else %>no posts<% end %></td> |
15 |
<% if admin? %><td><%= link_to "Edit", edit_forum_path(forum) %><% end %></td><% end %> |
16 |
<% if admin? %><td><%= link_to "Destroy", forum, :confirm => 'Are you sure?', :method => :delete %></td><% end %> |
17 |
</tr>
|
18 |
<% end %> |
19 |
</table>
|
20 |
|
21 |
<p><% if admin? %><%= link_to "New Forum", new_forum_path %></p> |
Wenn Sie nun versuchen, die Seite neu zu laden, wird eine Fehlermeldung mit der Meldung "undefinierte Methode" Berechtigungsstufe "angezeigt. Der Fehler weist darauf hin, dass es keine Spalte mit dem Namen allow_level gibt. Wir müssen eine Migration erstellen. Führen Sie daher die folgenden Befehle aus, um die Änderungen zu erstellen und zu migrieren:
1 |
script/generate migration add_permissions_to_users permission_level:integer |
2 |
rake db:migrate |
Jetzt sollte alles richtig funktionieren. Jetzt werden wir mit der Show-Aktion fortfahren. Öffnen Sie also app/views/forums/show.html.erb und bearbeiten Sie sie wie folgt:
1 |
# app/views/forums/show.html.erb |
2 |
<% title @forum.name %> |
3 |
|
4 |
<table>
|
5 |
<tr>
|
6 |
<th width="60%">Topic Title</th> |
7 |
<th width="10%">Replies</th> |
8 |
<th width="30%">Last Post</th> |
9 |
</tr>
|
10 |
<% for topic in @forum.topics %> |
11 |
<tr>
|
12 |
<td><%= link_to h(topic.name), topic_path(topic.id) %> |
13 |
<td><%= topic.posts.count - 1%></td> |
14 |
<td class="right"><%= distance_of_time_in_words_to_now topic.last_post_at %> ago by <%= link_to topic.user.username, "/users/#{topic.last_poster_id}" %></td> |
15 |
<% if admin? %><td><%= link_to "Destroy", topic, :confirm => 'Are you sure?', :method => :delete %></td><% end %> |
16 |
</tr>
|
17 |
<% end %> |
18 |
</table>
|
19 |
|
20 |
<p><% if logged_in? %><%= link_to "New Topic", "/topics/new?forum=#{@forum.id}" %><% end %></p> |
Wir haben nur den Administrator für die Zerstörungsaktion und die Aktion zum Erstellen von Themen nur angemeldet. Jetzt werden wir an der Aktion "Theme anzeigen" arbeiten. Die Datei lautet "app/views/topic/show.html.erb". Öffnen Sie es und bearbeiten Sie es so, dass es aussieht wie:
1 |
# app/views/topics/show.html.erb |
2 |
<% title @topic.name %> |
3 |
|
4 |
<% for post in @topic.posts %> |
5 |
<div class="post"> |
6 |
<span class="left"><%= link_to post.user.username, user_url(post.user) %><br /><% if logged_in? %><% if admin_or_owner?(post.user.id) %><%= link_to "Edit", edit_post_path(post) %><br /><%= link_to "Delete", post, :confirm => 'Are you sute?', :method => :delete %><% end %><% end %></span> |
7 |
<span class="right"><%= post.content %></span> |
8 |
</div>
|
9 |
<% end %> |
10 |
|
11 |
<p>
|
12 |
<% if logged_in? %><%= link_to "Reply", "#{new_post_path}?topic=#{@topic.id}" %> |<% end %> |
13 |
<% if admin? %><%= link_to "Destroy Topic", @topic, :confirm => 'Are you sure?', :method => :delete %> |<% end %> |
14 |
<%= link_to "View All", forum_path(@topic.forum_id) %> |
15 |
</p>
|
Wir haben wieder nur einige Methoden implementiert, damit nicht registrierte Benutzer und Benutzer, die nicht über genügend Berechtigungen verfügen, einige Links nicht sehen können. Nachdem wir die Links gesperrt haben, werden wir die Controller sperren. Öffnen Sie also zuerst app/controller/forum_controller.rb und fügen Sie rechts unter der Klassendeklaration Folgendes hinzu:
1 |
before_filter :admin_required, :except => [:index, :show] |
Wenn Sie jetzt Ihre Anwendung ausprobieren, werden Sie feststellen, dass Rails uns einen Fehler gibt, und das liegt daran, dass er admin_required nicht definiert hat. Um dies hinzuzufügen, definieren wir es in unserem Anwendungscontroller. Öffnen Sie es also und fügen Sie die folgende Methode direkt vor dem letzten End-Tag hinzu:
1 |
# app/controllers/application_controller.rb
|
2 |
def admin_required |
3 |
unless current_user && (current_user.permission_level == 1 || current_user.id == 1) |
4 |
redirect_to '/' |
5 |
end
|
6 |
end
|
Dies besagt, dass Sie, sofern wir kein Administrator sind, zur Startseite weiterleiten. Wir werden jetzt mit unserem Themen-Controller fortfahren, genau wie beim Foren-Controller, wir werden einige Vor-Filter hinzufügen und dieses Mal hinzufügen:
1 |
# app/controllers/topics_controller.rb
|
2 |
before_filter :login_required, :except => [:index, :show] |
3 |
before_filter :admin_required, :only => :destroy |
Wir sagen also, dass Sie für jede Aktion außer Index und Show angemeldet sein müssen und ein Administrator sein müssen, um auf die Zerstörungsaktion zugreifen zu können. Als nächstes werden wir an unserem Post-Controller arbeiten. Dieser wird ein bisschen mehr Arbeit sein. Fügen Sie zunächst den Vorher-Filter hinzu:
1 |
# app/controllers/posts_controller.rb
|
2 |
before_filter :login_required |
Als Nächstes fügen wir unserer Datei application_controller.rb eine zusätzliche Methode hinzu, um dies zu handhaben. Hier ist die Methode, die wir hinzufügen werden:
1 |
# app/controllers/application_controller.rb
|
2 |
def admin_or_owner_required(id) |
3 |
unless current_user.id == id || current_user.permission_level == 1 || current_user.id == 1 |
4 |
redirect_to '/' |
5 |
end
|
6 |
end
|
Diese Methode prüft, ob die an sie übergebene Benutzer-ID der ID unseres aktuellen Benutzers entspricht oder ob unser aktueller Benutzer ein Administrator ist. Kehren Sie zu unserem Posts-Controller zurück und bearbeiten Sie die Aktionen zum Bearbeiten, Aktualisieren und Zerstören, damit sie wie folgt aussehen:
1 |
# app/controllers/posts_controller.rb
|
2 |
def edit |
3 |
@post = Post.find(params[:id]) |
4 |
admin_or_owner_required(@post.user.id) |
5 |
end
|
6 |
|
7 |
def update |
8 |
@post = Post.find(params[:id]) |
9 |
admin_or_owner_required(@post.user.id) |
10 |
if @post.update_attributes(params[:post]) |
11 |
@topic = Topic.find(@post.topic_id) |
12 |
@topic.update_attributes(:last_poster_id => current_user.id, :last_post_at => Time.now) |
13 |
flash[:notice] = "Successfully updated post." |
14 |
redirect_to "/topics/#{@post.topic_id}" |
15 |
else
|
16 |
render :action => 'edit' |
17 |
end
|
18 |
end
|
19 |
|
20 |
def destroy |
21 |
@post = Post.find(params[:id]) |
22 |
admin_or_owner_required(@post.user.id) |
23 |
@post.destroy |
24 |
flash[:notice] = "Successfully destroyed post." |
25 |
redirect_to forums_url |
26 |
end
|
Nachdem wir die Authentifizierung durchgeführt haben, haben wir einen letzten Schritt.
Schritt 17 - Fertigstellen des Anwendungslayouts
Jetzt fügen wir unserer Anwendungslayoutdatei einen Header hinzu. Öffnen Sie die App/views/layouts/application.html.erb und fügen Sie direkt nach dem Body-Tag Folgendes hinzu:
1 |
# app/views/layouts/application.html.erb |
2 |
<div id="header"> |
3 |
<h1>My Forums!</h1> |
4 |
<% if logged_in? %> |
5 |
Welcome <%= current_user.username %>! Not you? |
6 |
<%= link_to "Log out", logout_path %> |
7 |
<% else %> |
8 |
<%= link_to "Sign up", signup_path %> or |
9 |
<%= link_to "log in", login_path %>. |
10 |
<% end %> |
11 |
</div>
|
Öffnen Sie nun unsere CSS-Datei und fügen Sie die folgende Zeile hinzu:
1 |
# public/stylesheets/application.css |
2 |
#header {width:75%; margin:0 auto;} |
Wenn Sie Ihren Webbrowser öffnen, sollte Folgendes angezeigt werden:
Abschluss
Ich hoffe, Ihnen hat dieses Tutorial gefallen, und wenn Sie sich durch diese Monstrosität hindurchbewegt haben, empfehle ich Ihnen! Wenn Sie nach einem Forum suchen, wäre dies kein schlechter Start, aber Beast (in diesem Fall veränderte_beast) ist ein großartiges Forum mit einem wirklich schönen und reibungslosen Design. Unten sehen Sie einen Bildschirm mit Statistiken zu unserem Programm. Für die Erstellung dieses Forums wurden 276 Codezeilen (ohne Ansichten) benötigt!



- Folgen Sie uns auf Twitter oder abonnieren Sie den NETTUTS RSS-Feed, um weitere tägliche Tipps und Artikel zur Webentwicklung zu erhalten.