Я предоставляю альтернативный подход, так как этот вопрос SO поднимается вверху при поиске ролевой маршрутизации в Rails.
Недавно мне нужно было реализовать что-то подобное, но мне хотелось избежать большого количества условностей в контроллере - это усугублялось тем фактом, что каждая из моих пользовательских ролей требовала загрузки и представления совершенно разных данных. Я решил переместить решающую логику на уровень маршрутизации, используя Ограничение маршрутизации .
# app/constraints/role_route_constraint.rb
class RoleRouteConstraint
def initialize(&block)
@block = block || lambda { |user| true }
end
def matches?(request)
user = current_user(request)
user.present? && @block.call(user)
end
def current_user(request)
User.find_by_id(request.session[:user_id])
end
end
Самой важной частью вышеуказанного кода является метод matches?
, который будет определить, будет ли маршрут соответствовать. Метод передается объекту request
, который содержит различную информацию о выполненном запросе. В моем случае я просматриваю :user_id
, хранящийся в cookie сессии, и используя это, чтобы найти пользователя, делающего запрос.
Затем вы можете использовать это ограничение при определении своих маршрутов.
# config/routes.rb
Rails.application.routes.draw do
get 'home', to: 'administrators#home', constraints: RoleRouteConstraint.new { |user| user.admin? }
get 'home', to: 'instructors#home', constraints: RoleRouteConstraint.new { |user| user.instructor? }
get 'home', to: 'students#home', constraints: RoleRouteConstraint.new { |user| user.student? }
end
С помощью вышеизложенного администратор, делающий запрос на /home
, будет перенаправлен на home действие AdministratorsController
, инструктор делает запрос к /home
будет перенаправлен на home действие InstructorsController
, а учащийся, сделавший запрос к /home
, будет перенаправлен на home действие StudentsController
.
Если вы ищете дополнительную информацию, я недавно написал об этом подходе в моем блоге .