Ruby on Rails - render layout

RyanJM picture RyanJM · Jul 14, 2009 · Viewed 28k times · Source

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?

Answer

molf picture molf · Jul 14, 2009

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.