Ответ 1
Существует несколько способов решения этой проблемы, как указывают другие ответы. Во-первых, убедитесь, что вы понимаете разницу между аутентификацией (создание пользователя и вход в систему) и авторизация на основе ролей (контроль доступа к различным частям веб-приложения в зависимости от роли пользователя). Вы можете реализовать аутентификацию самостоятельно, но большинство разработчиков Rails используют камень Devise, потому что он надежный, полнофункциональный и хорошо протестированный. Авторизация может быть реализована с помощью простых дополнений к модели пользователя, хотя разработчики часто используют CanCanCan или Pundit для сложных приложений.
В описываемом вами случае использования я рекомендую внедрить в вашей модели пользователя очень базовую форму авторизации на основе ролей. Сначала вам нужно создать модель User с помощью Devise.
Новая функция Active Record, Enum, введенная в Rails 4.1, является самым простым способом реализации авторизации на основе ролей.
Создать перенос:
$ rails generate migration AddRoleToUsers role:integer
Миграция будет выглядеть так:
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :integer
end
end
Добавить код в пользовательскую модель для реализации Enum:
class User < ActiveRecord::Base
enum role: [:student, :parent, :teacher, :admin]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :student
end
end
Вы определяете имена ролей и, при необходимости, можете изменять имена по мере необходимости (целочисленные значения, сохраненные с каждой пользовательской записью, остаются неизменными). Активная запись ограничивает присвоение атрибута коллекции предопределенных значений, поэтому вам не нужно добавлять какой-либо код, чтобы ограничить имена ролей определенным набором. Лучше всего, перечисления поставляются с набором удобных методов, которые позволяют вам напрямую запрашивать роль без какого-либо дополнительного кода. Для атрибута enum, показанного выше, вы можете использовать следующие методы:
User.roles # => {"student"=>0, "parent"=>1, "teacher"=>2, "admin"=>1} # list all roles
user.student! # make a student user
user.student? # => true # query if the user is a student
user.role # => "student" # find out the user’s role
@users = User.student # obtain an array of all users who are students
user.role = 'foo' # ArgumentError: 'foo' is not a valid, we can’t set invalid roles
Вы можете использовать условные обозначения в контроллере:
class UsersController < ApplicationController
def index
unless current_user.admin?
redirect_to :back, :alert => "Access denied."
end
@users = User.all
end
end
Или используйте его в представлении:
<% if current_user.parent? %>
<li><%= link_to 'Grade Reports', some_path %></li>
<% end %>
В общем случае, если управление доступом добавляет много кода контроллеру, вам рекомендуется использовать CanCanCan или Pundit, поскольку вы можете переместить сложную логику авторизации в центральное место, отделенное от контроллеров ( "тощие контроллеры" ). Однако, если ваши потребности так же просты, как вы описываете, роль авторизации на основе роли в контроллере является оптимальной.
Я написал учебное пособие > Rails Pundit, в котором сравниваются оба подхода и более подробно описывается простая авторизация на основе ролей, а также роль авторизация с Pundit.