Alternative Anwendungen für Rails’ Partials

Wenn man das DRY-Prinzip in Ruby on Rails erfolgreich umsetzten möchte, sind Partials das tägliche Brot. Dass Partials jedoch nicht nur für die simple Wiedergabe von Objekt-Sammlungen gut sind, versteht man vielleicht nicht auf Anhieb. Deshalb stelle ich hier zwei praktische Beispiele für alternative Anwendungen von Partials vor.

Lerne mehr über Ruby on Rails mit Martin Labuschins
Ruby on Rails Link Library.

Komplexe globale Navigationen

Wenn die Inhalte der globalen Navigation einer Webanwendung von verschiedenen Bedingungen (Sitzungsstatus, Benutzerlevel, etc.) abhängen, kann der dafür nötige Quelltext schnell an Masse gewinnen und somit beispielsweise die Layout-Datei unnötig unübersichtlich machen. Um das zu verhindern, kommt die einfachste Partial-Anwendung hier zum Einsatz. Wir verzichten hierbei auf alle weiteren Attribute der render-Funktion:

<%= render :partial => 'navigation' %>

app/views/layouts/application.html.erb

Der Quelltext für die Navigation kann nun getrost in die Partial-Datei ausgelagert werden. Anpassungen sind nicht nötig.

<ul id="navigation">
		<% @sections.each do |section| %>
			<li><%= link_to section.title, section %></li>
		<% end %>
		<% if logged_in? %>
			<li><%= link_to "Einstellungen", settings_path %></li>
			<li><%= link_to "Abmelden", logout_path %></li>
		<% else %>
			<li><%= link_to "Registrieren", signup_path %></li>
			<li><%= link_to "Anmelden", login_path %></li>
		<% end %>
		</ul>

app/views/layouts/_navigation.html.erb

Ähnliche Elemente smart wiedergeben

Nehmen wir an, eine Freunde-Seite eines Social Networking Service zeigt grundsätzlich alle Freunde eines Benutzers an.

<h2><% @user.gen_attr %> Freunde</h2>

		<p>Das sind alle Freunde von <%= @user.name %>.</p>

		<% unless @friendships.empty? %>
			<ul>
				<% @friendships.each do |friend| %>
					<li><%= link_to friend.name, friend %></li>
				<% end %>
			</ul>
		<% end %>

app/views/friendships/index.html.erb

Ein eingeloggter Benutzer soll auf seiner eigenen Freunde-Seite zusätzlich seine gesendeten und erhaltenen Freundschaftseinladungen sehen. Diese beiden Auflistungen sehen der eigentlichen Freunde-Liste sehr ähnlich. Hier eignet sich der Einsatz eines Partial mit vorbereiteten lokalen Variablen:

<!-- Alle Freunde -->
		<%= render :partial => 'friend_list', :locals => {
			:title => @user.attr_gen + ' Freunde',
			:description => 'Das sind alle Freunde von ' + @user.name,
			:friends => @friendships
		} %>

		<!-- Erhaltene Freundschaftsanfragen -->
		<%= render :partial => 'friend_list', :locals => {
			:title => 'Neue Freunde!',
			:description => 'Diese Benutzer möchten deine Freunde werden:',
			:friends => @requested_friendships
		} %>

		<!-- Gesendete Freundschaftsanfragen -->
		<%= render :partial => 'friend_list', :locals => {
			:title => 'Fast Freunde',
			:description => 'Diese Benutzer müssen die Freundschaft mit dir noch bestätigen:',
			:friends => @pending_friendships
		} %>

app/views/friendships/index.html.erb

Alle Schlüssel-Wert-Paare des mit :locals übergebenen Hash sind im Partial nun als lokale Variablen verfügbar. Es spielt im Partial also keine Rolle, ob es sich nun um die Wiedergabe von bestehenden, erhaltenen oder gesendeten Freundschaften handelt:

<% unless friends.empty? %>
			<h2><%= title %></h2>
			<p><%= description %></p>

			<ul>
				<% friends.each do |friend| %>
					<li><%= link_to friend.name, friend %></li>
				<% end %>
			</ul>
		<% end %>

app/views/friendships/_friend_list.html.erb


Schnell wird klar, dass Partials unverzichtbar für übersichtlichen und wartbaren Code in Views sind. Ich hoffe, ich konnte euch anregen, eigene Ideen für den Einsatz von Partials zu entwickeln.

veröffentlicht am 30.04.2008 um 22:00 von Martin Labuschin in ,


Hallo Martin,

die Idee mit der Navigation als partial hatte ich auch schon.
Ich hab's auch so gemacht wie Du, nämlich mit
<%= render :partial => 'navigation' %> im layouts/application.html.erb und habe die _navigation.html.erb in das gleiche Verzeichnis (layouts) gelegt.
Nur bei mir findet er das partial nicht, sondern sucht es immer im entsprechenden Unterverzeichnis der View die gerade angezeigt wird. In Deinem Beispiel wäre das dann etwa im views/friendships.
Ich habe es dann mit <%= render('layouts/_navigation') %> gemacht, was funktioniert.
Ich würde aber lieber die Partials nehmen, da ich hier auch Variablen übergeben kann.

Was muss ich denn einstellen, damit er das partial unter layouts sucht und nicht im Unterverzeichnis der gerade angezeigten View?

Danke
Heinz

Du hast die Lösung eigentlich schon fast selbst gefunden. Durch die Pfad-Angabe 'layouts/navigation' wird immer das Partial aus dem layout-Verzeichnis genommen. Besser kann man es nicht lösen:

<%= render :partial => 'layouts/_navigation', :locals => { :foo => 'bar'} %>

Hilft dir das weiter?

Hallo Martin,

danke für die Antwort. Mit vollqualifizierter Angabe (aber ohne _) funktioniert's.

<%= render :partial => 'layouts/navigation' , :locals => { :foo => 'bar'} %>

war genau das, was ich brauchte.

Danke
Heinz

blog comments powered by Disqus
The Ruby on Rails Link Library Spanning Sync SEO-Dokumentation Gowalla
ProWebApps WellDone (β) Pinboard (α) Netzwerk Münsterland
Blogs Bücher Frameworks iPhone Mac Web-Apps