score:0

assuming that these profiles are persisted in some form, a simple mechanism would be to have a field identifying them and to use that field(from the table(sql)/document(nosql)) to determine which features should be active or which templates to use.

score:0

i would use one action that handles the route /dashboard and have three different views, one for each kind of users. once a request received, the action will be able to know which kind of users is making the call and would respond with something like ok(views.html.customerdashboard) for example.

score:1

since the dashboard isn't really a resource, it's a context sensitive thing, i wouldn't worry about being restful as the other posts suggest. so, you have your profiles:

trait profile
case object adminprofile extends profile
case object customerprofile extends profile
case object companyprofile extends profile

and you have a method that extracts a profile from the request header:

def extractprofile(rh: requestheader): option[profile] = rh.session.get("profile").map {
  case "admin" => adminprofile
  case "customer" => customerprofile
  case "company" => companyprofile
}

you can just do this in your action:

def dashboard = action { req => 
  extractprofile(req).map {
    case adminprofile => // code here that loads stuff and renders it for admin
    case customerprofile => // code here for customer
    case companyprofile => // code here for company
  } getorelse notfound
}

let's say though that you wanted the admins to be able to access the customer or company dashboard, and so you already have the 3 routes as described in your original post, so you can go to a specific one if you want. you can easily add a fourth action that simply delegates /dashboard to the appropriate one. eg:

def dashboard = essentialaction { req =>
  extractprofile(req).map {
    case adminprofile => admin.dashboard(req)
    case customerprofile => customer.dashboard(req)
    case companyprofile => company.dashboard(req)
  } getorelse notfound
}

notice the use of essentialaction here. it's necessary if you want to compose multiple actions into one action.

score:4

if the profile should be hidden from the url point of view (not restful ^^). you can hide it, either in the flash scope or session one, regarding the length of the flows.

now, for the routing part, it's yet another story. since you can route (in the route file) using 'hidden' values, you won't be able to represent these routes in the configuration.

however, you could do you own action interceptor that extract the profile and redirect to the right dashboard (this is probably the quick and dirtiest manner)...

at last, couldn't you just use the profile in the path ;-) ?

get /dashboard           dashboard.index
get /admin/dashboard     admin.dashboard
get /customer/dashboard  customer.dashboard
get /company/dashboard   company.dashboard

controller... but doesn't scale for further calls if needed...

object dashboard extends controller {

  def index = action { implicit request =>
    request.session.get("profile").map {  p =>
      p match {
        case "admin" => redirect( routes.admin.dashboard() )
        case "customer" => redirect( routes.customer.dashboard() )
        case "company" => redirect( routes.company.dashboard() )
      }
    }.getorelse { 
      redirect( routes.customer.dashboard() )
    } 
  }

}

Related Query

More Query from same tag