Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PC-67: AdminUsers management in ActiveAdmin #46

Merged
merged 8 commits into from
Mar 24, 2025
Merged
65 changes: 56 additions & 9 deletions app/admin/admin_users.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,74 @@
ActiveAdmin.register AdminUser do
permit_params :email, :password, :password_confirmation
permit_params :email, :name, :password

action_item :back, only: :show do
link_to 'Back to Admin Users', admin_admin_users_path
end

filter :name
filter :email

index do
selectable_column
id_column
column :name
column :email
column :current_sign_in_at
column :sign_in_count
column :created_at
column :last_sign_in_at
actions
end

filter :email
filter :current_sign_in_at
filter :sign_in_count
filter :created_at
show do
attributes_table do
row :id
row :name
row :email
row :created_at
end
end

form do |f|
f.inputs do
f.input :name
f.input :email
f.input :password
f.input :password_confirmation
f.input :password, required: resource.new_record?
end
f.actions
end

controller do
def update
@admin_user = AdminUser.find(permitted_params[:id])

if update_admin_user
redirect_to admin_admin_user_path(@admin_user), notice: 'Admin user was successfully updated.'
else
render :edit
end
end

def create
@admin_user = AdminUser.new(admin_user_params)

if @admin_user.save
redirect_to admin_admin_users_path, notice: 'Admin user was successfully created.'
else
render :new
end
end

private

def update_admin_user
if admin_user_params[:password].present?
@admin_user.update(admin_user_params)
else
@admin_user.update_without_password(admin_user_params)
end
end

def admin_user_params
permitted_params[:admin_user]
end
end
end
33 changes: 27 additions & 6 deletions app/models/admin_user.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
class AdminUser < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :recoverable,
:rememberable, :validatable
devise :database_authenticatable,
:rememberable,
:trackable

PASSWORD_SYMBOL_FORMAT = /\A(?=.*[^\w\s])[^\s]*\z/
PASSWORD_REPEATED_CHAR_FORMAT = /\A(?!.*(.)\1\1).*\z/

validates :name, presence: true
validates :email, presence: true, uniqueness: true,
format: { with: URI::MailTo::EMAIL_REGEXP, message: "must be a valid email format" }
validates :email, presence: true
validates :email, uniqueness: true,
format: { with: URI::MailTo::EMAIL_REGEXP,
message: "must be a valid email format" }, if: -> { email.present? }
validates :password, presence: true, unless: :skip_password_validation?
validates :password, length: { minimum: 8, maximum: 128 },
format: { with: PASSWORD_SYMBOL_FORMAT, message: "must contain at least one symbol" }
validates :password, format: { with: PASSWORD_REPEATED_CHAR_FORMAT, message: "must not contain repeated characters" }
format: { with: PASSWORD_SYMBOL_FORMAT,
message: "must contain at least one symbol" },
unless: :skip_password_validation?, if: -> { password.present? }
validates :password, format: { with: PASSWORD_REPEATED_CHAR_FORMAT,
message: "must not contain repeated characters" },
unless: :skip_password_validation?, if: -> { password.present? }

def update_without_password(params)
@skip_password_validation = true
super(params)
ensure
@skip_password_validation = false
end

def self.ransackable_attributes(_auth_object = nil)
%w[created_at email encrypted_password id id_value name remember_created_at
reset_password_sent_at reset_password_token updated_at]
end

private

def skip_password_validation?
@skip_password_validation || false
end
end
11 changes: 11 additions & 0 deletions db/migrate/20250318094556_add_trackable_to_admin_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class AddTrackableToAdminUsers < ActiveRecord::Migration[8.0]
def change
change_table :admin_users, bulk: true do |t|
t.column :sign_in_count, :integer, default: 0, null: false
t.column :current_sign_in_at, :datetime
t.column :last_sign_in_at, :datetime
t.column :current_sign_in_ip, :string
t.column :last_sign_in_ip, :string
end
end
end
7 changes: 6 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions spec/requests/admin/admin_users_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'rails_helper'

RSpec.describe "Admin::AdminUsersController", type: :request do
let!(:admin_user) { create(:admin_user) }

let(:admin_user_params) do
{ email: '[email protected]',
name: 'test',
password: 'password@123' }
end

before do
sign_in admin_user, scope: :admin_user
end

describe "routes" do
context 'GET /admin/admin_users/new' do
it "should get new" do
get new_admin_admin_user_path

expect(response).to have_http_status(:ok)
end
end

context 'POST /admin/admin_users' do
let(:last_admin_user) { AdminUser.last }

it 'creates the model successfully and redirects to index' do
post admin_admin_users_path, params: { admin_user: admin_user_params }

expect(response).to redirect_to(admin_admin_users_path)

follow_redirect!

expect(response.body).to include('Admin user was successfully created.')
expect(last_admin_user.email).to be_eql admin_user_params[:email]
end
end

context 'GET /admin/admin_users/:id/edit' do
it "should get edit" do
get edit_admin_admin_user_path(admin_user)

expect(response).to have_http_status(:ok)
end
end

context 'PATCH /admin/admin_users/:id' do
it 'updates the email successfully and redirects to show' do
patch admin_admin_user_path(admin_user), params: { admin_user: { email: '[email protected]' } }

expect(response).to redirect_to(admin_admin_user_path(admin_user))

follow_redirect!

expect(response.body).to include('Admin user was successfully updated.')
expect(admin_user.reload.email).to be_eql '[email protected]'
end
end
end
end