One controller, different views for normal users and admins

cite picture cite · Aug 24, 2009 · Viewed 7.7k times · Source

in my application, I have a "User" model. Each user can have multiple (email) addresses which are defined in the model "Address":

Class User < ActiveRecord::Base
  has_many :addresses


  def is_authorized(op)
     # returns true or false
  end

  def is_owned_by(user)
     # returns true or false
  end
end

Class Address < ActiveRecord::Base
  belongs_to :user
end

Inside the AddressController class, the currently logged in user is available in the "@user" instance variable. The controller prevents ordinary users from editing, deleting, viewing etc. addresses which don't belong to them - but he does allow an administrative user to edit those. The AddressController class can ask the AddressModel if the user currently logged in is performing normal or superuser operations.

This all works nicely and database updates are made as expected, however, I'd really like to have different HTML views depending on the mode of operation. I can only think of two ways to achieve that:

  1. Make the mode of operation (normal/privileged) known in the AddressController class (using an instance variable, e.g. @privileged) and use an "if" statement in the view.
  2. Use something like an "after_filter" in the address controller to render a different layout.

If it is possible to display the results of executing a single controller in two completely different layouts, depending on it's mode of operation, what is a good way to achieve that?

Thanks in advance Stefan

Answer

Shadwell picture Shadwell · Aug 24, 2009

You can specify which view to use to display the result of an action in the action itself. You can also specify which layout to use too. So, for example:

def my_action
  if @user.is_authorised(...)
    render :action => 'admin_action', :layout => 'admin'
  else
    render :action => 'non_admin_action', :layout => 'non_admin'
  end
end

This will render either admin_action.html.erb or non_admin_action.html.erb depending on the returned value from is_authorised. The :layout option is, er, optional and refers a layout in views/layouts. There are various other options the render call which you can find in the documentation for render.