21

I'm trying to split up a web site into two sections. One which should use the application layout and one that should use the admin layout. In my application.rb I created a function as follows:

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

And in the controllers where it might be one or the other I put

before_filter :admin_layout 

This works fine for some pages (where its just text) but for others I get the classic error:

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 

Does anyone have an idea of what I'm missing? How should I properly use render and layout?

5 Answers 5

43

The method render will actually attempt to render content; you should not call it when all you want to do is set the layout.

Rails has a pattern for all of this baked in. Simply pass a symbol to layout and the method with that name will be called in order to determine the current layout:

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.

Sign up to request clarification or add additional context in comments.

4 Comments

if logged_in? and current_user.is_able_to('siteadmin') as current_user may be nil if not logged in!
I have other checks before that line to check for if a user is logged in. That is amazing though, I never even thought about calling a function after layout. So simple and very helpful. Thank you.
For those who are checking this out. I should have done a little more research: apidock.com/rails/ActionController/Layout/ClassMethods/layout the first comment would have answered my question.
@molf the link in your answer is broken
5

perhaps you need to check that the user is signed in first?

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

1 Comment

.nil? on the unless statement is redundant though
1

It might be because current_user is nil when the user is not logged in. Either test for .nil? or initialize the object.

Comments

0

Try molf's answer with:

if logged_in? and current_user.is_able_to('siteadmin')

Comments

0

Your current user is properbly set in the after the user has logged in. and in this case you should have an option to determine if you are logged in

like

 if !@current_user.nil? if @current_user.is_able_to("###") render :layout => "admin" else render :layout => "application" end end 

Then it will only enter the if statement if your @current_user in not nil.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.