В основе данной публикации лежит чудная статья How to Implement a Single User Model with Rails, ActiveAdmin, and Devise от Daniel Doezema, не утратившая (дата публикции FEBRUARY 25, 2012), на мой взгляд, актуальности и по сегодняшний день; пришлось, правда, внести некоторые правки в предложенный автором код, дабы учесть ряд изменившихся особенностей Rails и современные реалии. Крайне интересно, как мне показалось, изменить функционал ActiveAdmin, работающей в связке с Devise, таким образом, чтобы учетные записи - администраторов, имеющих доступ к Dashboard ActiveAdmin, и зарегистрированных пользователей, данного доступа не имеющие - были бы реализованы посредством одной и той же модели User, а для перехода из одной группы в другую достаточно было бы добавить/удалить boolean flag (чекбокс superadmin). Регистрация пользователей происходит непосредственном через форму devise, и созданная таким образом учетная запись полностью доступна для администрирования в панели управления ActiveAdmin. Поверьте, действительно удобно.
Пошаговое, step-by-step это описание не избавит вас от необходимости допила конфигурации ActiveAdmin "под себя", также увлекательной ловли мелких багов (например, комментарии ActiveAdmin можно полностью отключить в /config/initializers/active_admin.rb, хотя у меня они включены и вполне нормально работают), тем не менее, описанный способ реализации пользовательской аутентификации на основе ActiveAdmin / Devise вполне работоспособен при использовании актуальных, на момент публикации материала, версиях ПО: тестировал на ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux], Rails 5.1.4, activeadmin (2.0.0.alpha), devise (4.3.0).
Итак, к делу. Последовательность действий предполагает, что вы уже создали rails-проект, Gemfile которого содержит гемы devise и activeadmin:
gem 'activeadmin', github: 'activeadmin'
gem 'devise'
Далее:
rails generate active_admin:install
rails generate devise:install
Примечание. Вводим «Y» ( да ), если будет предложено перезаписать файл инициализатора проекта:
conflict config/initializers/devise.rb
Overwrite config/initializers/devise.rb? (enter "h" for help) [Ynaqdh] Y
Создаем модель User:
rails generate devise User
и добавляем чекбокс superuser, отметка которого в дальнейшем позволит логиниться не только в веб-интерфейс приложения, но и в административную панель ActiveAdmin:
rails generate migration AddSuperadminToUser
Редактируем сформированный файл миграции, приводя к следующему:
class AddSuperadminToUser < ActiveRecord::Migration[5.1]
def up
add_column :users, :superadmin, :boolean, :null => false, :default => false
User.create! do |r|
r.email = Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. '
r.password = 'password'
r.superadmin = true
end
end
def down
remove_column :users, :superadmin
User.find_by_email(Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. ').try(:delete)
end
end
Теперь раскомментируем/отредактируем эти строчки в файле config/initializers/active_admin.rb :
config.site_title = "Project_name"
config.authentication_method = :authenticate_active_admin_user!
config.current_user_method = :current_user
config.logout_link_path = :destroy_user_session_path
config.batch_actions = true
config.localize_format = :long
Файл app/controllers/application_controller.rb выглядит у нас с вами следующим образом:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def authenticate_active_admin_user!
authenticate_user!
unless current_user.superadmin?
flash[:alert] = "Unauthorized Access!"
redirect_to root_path
end
end
end
А вот теперь - удаляем старую, ненужную нам модель:
rails destroy model AdminUser
, также необходимо удалить файл миграции::
**********_devise_create_admin_users.rb
В файле миграции ***************_create_active_admin_comments.rb меняем все active_admin_comments - на user_comments.
Удаляем из routes.rb следующую строчку:
devise_for :admin_users, ActiveAdmin::Devise.config
, взамен добавляем, например:
Rails.application.routes.draw do
devise_for :users
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
Создаем файл user.rb :
/app/admin/user.rb
ActiveAdmin.register User do
form do |f|
f.inputs "User Details" do
f.input :email
f.input :password
f.input :password_confirmation
f.input :superadmin, :label => "Super Administrator"
end
f.actions
end
create_or_edit = Proc.new {
@user = User.where(id: params[:id]).first_or_create
@user.superadmin = permitted_params[:user][:superadmin]
@user.attributes = permitted_params[:user].delete_if do |k, v|
(k == "superadmin") ||
(["password", "password_confirmation"].include?(k) && v.empty? && !@user.new_record?)
end
if @user.save
redirect_to :action => :show, :id => @user.id
else
render active_admin_template((@user.new_record? ? 'new' : 'edit') + '.html.erb')
end
}
member_action :create, :method => :post, &create_or_edit
member_action :update, :method => :put, &create_or_edit
permit_params :email, :password, :password_confirmation, :superadmin
end
Вот, пожалуй, и все.
rails s