Custom Authentication
Alchemy does not ship with its own authentication. The alchemy-devise gem provides a ready-made solution using Devise, but you can use any authentication system.
You only need to tell Alchemy about your user class and implement a few methods. This guide covers configuration, the required alchemy_roles method, and recommended methods for a full integration.
Configuration
Tell Alchemy about your user class and authentication paths in an initializer.
Available Options
| Option | Default | Description |
|---|---|---|
user_class | "User" | Your user model class name |
login_path | "/login" | Path to the login form |
logout_path | "/logout" | Path to the logout action |
logout_method | "delete" | HTTP verb for the logout action |
signup_path | "/signup" | Path to the signup form |
current_user_method | :current_user | Controller method that returns the current user |
user_class_primary_key | :id | Primary key column of your user model (useful for UUIDs) |
Alchemy 8.1+ 8.1+
# config/initializers/alchemy.rb
Alchemy.configure do |config|
config.user_class = "Admin"
config.login_path = "/auth/login"
config.logout_path = "/auth/logout"
config.logout_method = "delete"
endAlchemy 8.0 8.0
# config/initializers/alchemy.rb
Alchemy.user_class_name = "Admin"
Alchemy.login_path = "/auth/login"
Alchemy.logout_path = "/auth/logout"WARNING
This syntax is deprecated since Alchemy 8.1 and will be removed in a future version.
Required
The only method Alchemy needs from your user class is alchemy_roles. It must return an array of strings containing at least one of these roles:
memberauthoreditoradmin
# app/models/user.rb
def alchemy_roles
if admin?
%w(admin)
else
%w(member)
end
endTIP
You can use your own authorization system to determine the role. Alchemy only needs an array with at least one of the roles listed above.
Recommended
These methods and associations are not strictly required, but without them parts of the admin interface will show missing or placeholder information.
name
Used on the dashboard to greet the user ("Welcome back, [name]") and in the online users list. Without it, the greeting will be blank.
def name
read_attribute(:email)
endalchemy_display_name
Shown in the "logged in as" area at the top right of the admin interface, and used for creator/updater/locker names on pages. Without it, these will show "unknown".
def alchemy_display_name
"#{firstname} #{lastname}".strip
endlanguage
A locale string for the user's preferred translation of the Alchemy admin interface. The user can always switch the language manually, but this sets the default.
def language
"nl"
endTIP
In a real application you would store this as a column in the users table.
admins
Class method that returns a collection of admin users. Used to check if any admins exist (e.g. for signup eligibility).
def self.admins
where(admin: true)
endPage Tree Folding
Alchemy remembers which pages a user has folded or expanded in the admin page tree. To enable this, add the following association:
has_many :folded_pages, class_name: "Alchemy::FoldedPage"Without this, the page tree will work but folding state won't be persisted per user.
Change Tracking
Alchemy stores creator_id and updater_id on records like pages, elements, and pictures. To track which user created or updated these records, add these columns to your users table:
bin/rails g migration AddCreatorIdAndUpdaterIdToUsers creator_id:integer:index updater_id:integer:index
bin/rails db:migrateOptional
Tagging
If you want your users to be taggable, include the Alchemy::Taggable module:
class User < ApplicationRecord
include Alchemy::Taggable
endThis adds Gutentag-based tagging with the following methods:
tag_names/tag_list-- get or set tagstag_list=-- set tags from a comma-separated string or arrayUser.tagged_with(["tag1", "tag2"])-- find tagged recordsUser.tag_counts-- list all unique tags
Complete Example
class User < ApplicationRecord
include Alchemy::Taggable
has_many :folded_pages, class_name: "Alchemy::FoldedPage"
def alchemy_roles
if admin?
%w(admin)
else
%w(member)
end
end
def name
email
end
alias_method :alchemy_display_name, :name
def self.admins
where(admin: true)
end
end