Come posso redirect il percorso home dell’utente (root) in base al loro ruolo utilizzando Devise?

Sto lavorando a un’app di gestione del progetto e nell’app ho project_managers e client . Sto usando Devise e CanCan per l’autenticazione / authorization.

A che punto dopo l’accesso dovrei redirect l’utente al proprio controller / layout / viste specifico? C’è un modo per verificare current_user.role in routes.rb e impostare il root (o il reindirizzamento) in base al fatto che siano o meno un project manager o un client? Questo è un cambiamento che posso apportare a Devise da qualche parte?

Grazie in anticipo per qualsiasi aiuto! –Marchio

Il routes.rb file routes.rb non avrà alcuna idea del ruolo che l’utente ha, quindi non sarai in grado di usarlo per assegnare percorsi root specifici.

Quello che puoi fare è impostare un controller (ad esempio, passthrough_controller.rb ) che a sua volta può leggere il ruolo e il reindirizzamento. Qualcosa come questo:

 # passthrough_controller.rb class PassthroughController < ApplicationController def index path = case current_user.role when 'project_manager' some_path when 'client' some_other_path else # If you want to raise an exception or have a default root for users without roles end redirect_to path end end # routes.rb root :to => 'passthrough#index' 

In questo modo, tutti gli utenti avranno un punto di accesso, che a sua volta li reindirizza al controller / azione appropriato in base al ruolo.

La soluzione più semplice è usare lambda :

 root :to => 'project_managers#index', :constraints => lambda { |request| request.env['warden'].user.role == 'project_manager' } root :to => 'clients#index' 

Un’altra opzione è passare un proc al metodo authenticated come questo (sto usando rolify in questo esempio):

 authenticated :user, ->(u) { u.has_role?(:manager) } do root to: "managers#index", as: :manager_root end authenticated :user, ->(u) { u.has_role?(:employee) } do root to: "employees#index", as: :employee_root end root to: "landing_page#index" 

Si noti che in Rails 4 è necessario specificare un nome univoco per ogni instradamento principale, vedere questo problema per i dettagli.

Lo faccio in un’app Rails 3 che utilizza Warden. Poiché Devise è costruito su Warden, penso che funzionerà per te, ma assicurati di sperimentarlo un po ‘prima di fare affidamento su di esso.

 class ProjectManagerChecker def self.matches?(request) request.env['warden'].user.role == 'project_manager' end end # routes.rb get '/' => 'project_managers#index', :constraints => ProjectManagerChecker get '/' => 'clients#index' 

Se il ruolo dell’utente è “project_manager” verrà utilizzato ProjectManagersController – se non lo sarà, verrà utilizzato ClientsController. Se non sono loggati affatto, env['warden'].user sarà nullo e riceverai un errore, quindi probabilmente vorrai ovviare a questo, ma questo ti aiuterà a iniziare.