MySQL
MySQL is supported by the core better_auth gem through the direct MySQL
adapter. Rails applications can use better_auth-rails with ActiveRecord on top
of MySQL.
Use the lambda form when configuring the direct adapter. Better Auth passes the
final configuration into the lambda, so the adapter sees plugins, custom model
names, custom field names, and advanced.database.generate_id.
Install Dependencies
gem "better_auth"
gem "mysql2"bundle installExample Usage
require "better_auth"
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL"),
database: ->(options) {
BetterAuth::Adapters::MySQL.new(
options,
url: ENV.fetch("DATABASE_URL")
)
}
)You may also pass an existing Mysql2::Client when your app owns connection
management.
require "mysql2"
client = Mysql2::Client.new(
host: "localhost",
username: "root",
password: ENV.fetch("MYSQL_PASSWORD"),
database: "app_development",
symbolize_keys: false
)
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: ->(options) {
BetterAuth::Adapters::MySQL.new(
options,
connection: client
)
}
)Rails
Rails apps should normally use better_auth-rails and the ActiveRecord adapter.
gem "better_auth-rails"
gem "mysql2"bin/rails generate better_auth:install
bin/rails db:migrateSchema generation & migration
The Ruby schema helpers generate MySQL DDL from the same Better Auth
configuration used at runtime, including plugins, custom model names, custom
field names, and additional_fields.
MySQL Schema Generation | MySQL Schema Migration |
|---|---|
| ✅ Supported | ✅ Supported |
config = BetterAuth::Configuration.new(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: :memory,
plugins: []
)
statements = BetterAuth::Schema::SQL.create_statements(
config,
dialect: :mysql
)
puts statements.join("\n\n")require "better_auth"
require "mysql2"
config = BetterAuth::Configuration.new(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: :memory,
plugins: []
)
statements = BetterAuth::Schema::SQL.create_statements(
config,
dialect: :mysql
)
client = Mysql2::Client.new(
host: "localhost",
username: "root",
password: ENV.fetch("MYSQL_PASSWORD"),
database: "app_development",
symbolize_keys: false
)
statements.each { |sql| client.query(sql) }Joins (Experimental)
Enable experimental joins when you want Better Auth to ask the database adapter to fetch related records in one adapter call.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
experimental: { joins: true },
database: ->(options) {
BetterAuth::Adapters::MySQL.new(
options,
url: ENV.fetch("DATABASE_URL")
)
}
)The MySQL adapter supports native joins for core relationships and for plugin
schema relationships declared with references. Rails uses generated
ActiveRecord associations for the same schema-driven relationships.
Schema
The Ruby schema maps Better Auth logical fields to MySQL physical columns.
| Better Auth field | MySQL column |
|---|---|
emailVerified | email_verified |
userId | user_id |
createdAt | created_at |
expiresAt | expires_at |
MySQL DDL uses InnoDB, utf8mb4, json for JSON-like fields, datetime(6)
for date fields, and varchar(191) for indexed strings. Ids are generated as
hex strings by default. Set
advanced: { database: { generate_id: "uuid" } } to generate UUID strings
instead.
Additional Information
- The direct adapter supports the shared Better Auth CRUD contract, where operators, sorting, pagination, counts, transactions, and native joins.
- If you pass your own
Mysql2::Client, configure connection settings such as timezone/session behavior in that client before handing it to Better Auth. - Rails apps should prefer Rails migrations generated by
better_auth-rails; direct SQL generation is intended for non-Rails apps or custom migration workflows.