2009-07-14 14 views
17

Ich versuche, eine Website in zwei Abschnitte aufzuteilen. Eine, die das Anwendungslayout verwenden sollte und eine, die das Admin-Layout verwenden sollte. In meinem application.rb habe ich eine Funktion wie folgt:Ruby on Rails - Render-Layout

def admin_layout 
    if current_user.is_able_to('siteadmin') 
    render :layout => 'admin' 
    else 
    render :layout => 'application' 
    end 
end 

Und in den Controller, auf denen könnte es die eine oder andere sein habe ich

before_filter :admin_layout 

Dies funktioniert für einige Seiten in Ordnung (wo seine nur Text) aber für andere bekomme ich den klassischen Fehler:

You have a nil object when you didn't expect it! 
You might have expected an instance of Array. 
The error occurred while evaluating nil.each 

Hat jemand eine Idee von dem, was ich vermisse? Wie sollte ich Render und Layout richtig verwenden?

Antwort

38

Die Methode render versucht tatsächlich, Inhalt zu rendern; Sie sollten es nicht aufrufen, wenn Sie nur das Layout festlegen möchten.

Rails hat ein Muster für alle diese gebacken einfach ein Symbol layout und die Methode mit diesem Namen, um das aktuelle Layout zu bestimmen aufgerufen wird passieren.

class MyController < ApplicationController 
    layout :admin_layout 

    private 

    def admin_layout 
    # Check if logged in, because current_user could be nil. 
    if logged_in? and current_user.is_able_to('siteadmin') 
     "admin" 
    else 
     "application" 
    end 
    end 
end 

See details here.

+1

wenn logged_in redundant? und current_user.is_able_to ('siteadmin') als current_user kann Null sein, wenn nicht angemeldet! –

+0

@Reuben, das ist ein guter Punkt; hinzugefügt. – molf

+0

Ich habe andere Checks vor dieser Zeile zu überprüfen, ob ein Benutzer angemeldet ist. Das ist erstaunlich, obwohl ich nie darüber nachgedacht habe, eine Funktion nach dem Layout aufzurufen. So einfach und sehr hilfreich. Vielen Dank. – RyanJM

5

vielleicht müssen Sie überprüfen, dass der Benutzer zuerst angemeldet ist?

def admin_layout 
    if current_user and current_user.is_able_to 'siteadmin' 
    render :layout => 'admin' 
    else 
    render :layout => 'application' 
    end 
end 
+0

.nil? auf der unless-Anweisung ist jedoch – Gav

1

Es könnte sein, weil current_usernil ist, wenn der Benutzer nicht angemeldet ist. Entweder Test für .nil? oder initialisieren Sie das Objekt.

0

Versuchen molf's antwort mit:

wenn logged_in? und current_user.is_able_to (‚Siteadmin‘)

0

Ihr aktueller Benutzer properbly in der, nachdem der Benutzer gesetzt hat angemeldet. und in diesem Fall sollten Sie eine Option, um festzustellen, ob Sie in

wie

angemeldet sind

Dann wird es nur die if-Anweisung eingeben, wenn Ihr @ current_user nicht NULL ist.