http://minhajuddin.com/2011/10/24/how-to-change-the-rails-root-url-based-on-the-user-or-role/

отаю над приложением по управлению проектами, и в приложении у меня естьМенеджеры проекта а такжеклиенты, Я использую Devise и CanCan для аутентификации / авторизации.

В какой момент после входа в систему я должен перенаправить пользователя на его собственный конкретный контроллер / макет / представления? Есть ли способ проверитьcurrent_user.role вroutes.rb и установить рут (или перенаправление) в зависимости от того, являются ли они менеджером проекта или клиентом? Это изменение, которое я могу сделать где-нибудь в Devise?

Заранее благодарю за любую помощь! --Отметка

 Skilldrick21 янв. 2011 г., 00:33
Я задал похожий вопрос:stackoverflow.com/questions/3799393/... - ответ был создать отдельный контроллер для домашней страницы, которая выполняет маршрутизацию. Вы не можете получить доступ к этой информации Devise внутри rout.rb.

Ответы на вопрос(5)

Самое простое решение - использоватьlambda:

root :to => 'project_managers#index', :constraints => lambda { |request| request.env['warden'].user.role == 'project_manager' }
root :to => 'clients#index'
 Steve13 мар. 2019 г., 18:32
Предполагается, что можно использовать proc / lambda для:to вариант (root to: proc { |env| ...}), но я столкнулся с различными проблемами, так как кажется, чтоurl_for, Это решение работало без сбоевurl_for, +1!
 elquimista06 апр. 2016 г., 05:19
Это сработало для меня. У меня есть вопрос, хотя. Я использую Ruby 2.3.0, и он позволяет мне использовать новый стабильный лямбда-синтаксис. Но я получаю синтаксическую ошибку сconstraints: -> { ... }, Работает нормально, если я используюlambda вместо->, Есть идеи по этому поводу?

которое использует Warden. Поскольку Devise построен поверх Warden, я думаю, что он будет работать для вас, но обязательно поэкспериментируйте с ним, прежде чем полагаться на него.

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'

Если роль пользователя - «project_manager», будет использоваться ProjectManagersController - если это не так, будет использоваться ClientsController. Если они не вошли в систему вообще,env['warden'].user будет ноль, и вы получите ошибку, так что вы, вероятно, захотите обойти это, но это поможет вам начать.

 Mark21 янв. 2011 г., 16:01
Спасибо за ответы! Сначала я попробовал это, но не смог заставить его работать (вероятно, потому что я новичок в этом). Не говоря уже о - я с трудом могу понять, что я делаю в этот момент, поэтому идея «экспериментировать с ним» страшна до чертиков!

Другой вариант - передать процесс вauthenticated метод, подобный этому (я использую rolify в этом примере):

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"

Обратите внимание, что в Rails 4 выимеют чтобы указать уникальное имя для каждого корневого маршрута, см.Эта проблема для деталей.

 mmike12 дек. 2018 г., 09:39
давайте проголосуем за этот ответ! должны быть приняты как правильные
 Hoang Le19 авг. 2015 г., 06:09
это решение очень чисто с обновленным синтаксисом
Решение Вопроса

routes.rb Файл не будет иметь никакого представления о роли пользователя, поэтому вы не сможете использовать его для назначения определенных корневых маршрутов.

Что вы можете сделать, это настроить контроллер (например,passthrough_controller.rb) который в свою очередь может прочитать роль и перенаправить. Что-то вроде этого:

# 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'

Таким образом, у всех пользователей будет одна точка входа, которая, в свою очередь, перенаправит их на соответствующий контроллер / действие в зависимости от их роли.

 counterbeing19 февр. 2013 г., 14:58
Это хорошо работает для меня. Я решил выбросить его в свой контроллер приложений, и все выглядит просто замечательно ... Но есть ли какая-то причина, по которой вы установили новый контроллер для него? Просто интересно, если я что-то упускаю.
 Wolfgang08 мар. 2012 г., 09:43
Элегантное решение, которое не требует изменения какого-либо существующего кода, т.е. я могу сохранить всеredirect_to root_path заявления, как они были раньше. Мне это нравится :)
 Mark21 янв. 2011 г., 15:58
Спасибо человек, это полностью сработало.
 Khaja Minhajuddin24 окт. 2011 г., 11:42
stackoverflow.com/questions/4753871/... это лучшая реализация, так как она не создает новый контроллер только для перенаправления. Кроме того, это приведет к 1 дополнительной передаче от браузера к серверу каждый раз, когда пользователь перенаправляется на root_path

Ваш ответ на вопрос