PostgreSQL
PostgreSQL is supported by the core better_auth gem through the direct
PostgreSQL adapter. Rails applications can use better_auth-rails with
ActiveRecord on top of PostgreSQL.
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 "pg"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::Postgres.new(
options,
url: ENV.fetch("DATABASE_URL")
)
}
)You may also pass an existing PG::Connection when your app owns connection
management.
require "pg"
connection = PG.connect(ENV.fetch("DATABASE_URL"))
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: ->(options) {
BetterAuth::Adapters::Postgres.new(
options,
connection: connection
)
}
)Rails
Rails apps should normally use better_auth-rails and the ActiveRecord adapter.
gem "better_auth-rails"
gem "pg"bin/rails generate better_auth:install
bin/rails db:migrateRails uses ActiveRecord by default:
BetterAuth::Rails.configure do |config|
config.database_adapter = :active_record
endSchema generation & migration
The Ruby schema helpers generate PostgreSQL DDL from the same Better Auth
configuration used at runtime, including plugins, custom model names, custom
field names, and additional_fields.
PostgreSQL Schema Generation | PostgreSQL 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: :postgres
)
puts statements.join("\n\n")require "better_auth"
require "pg"
config = BetterAuth::Configuration.new(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: :memory,
plugins: []
)
statements = BetterAuth::Schema::SQL.create_statements(
config,
dialect: :postgres
)
connection = PG.connect(ENV.fetch("DATABASE_URL"))
statements.each { |sql| connection.exec(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::Postgres.new(
options,
url: ENV.fetch("DATABASE_URL")
)
}
)The PostgreSQL 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 PostgreSQL physical columns.
| Better Auth field | PostgreSQL column |
|---|---|
emailVerified | email_verified |
userId | user_id |
createdAt | created_at |
expiresAt | expires_at |
JSON-like fields use jsonb, date fields use timestamptz, and 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 use a non-default PostgreSQL schema, configure the connection search path before the adapter runs and make sure the schema already exists.
- Rails apps should prefer Rails migrations generated by
better_auth-rails; direct SQL generation is intended for non-Rails apps or custom migration workflows.