Configuration¶
Ralph is designed to be easy to configure while providing flexibility for different environments and database backends.
The Configure Block¶
The primary way to configure Ralph is through the Ralph.configure block. This block allows you to set global settings for the ORM, such as the database backend.
require "ralph"
Ralph.configure do |config|
config.database = Ralph::Database::SqliteBackend.new("sqlite3://./db.sqlite3")
end
Settings Options¶
Currently, Ralph supports the following configuration options:
| Option | Type | Description |
|---|---|---|
database |
Ralph::Database::Backend? |
The database backend to use for all operations. |
Database Backends¶
Ralph uses a pluggable backend architecture. Currently, it supports SQLite and PostgreSQL.
SqliteBackend¶
The SqliteBackend is initialized with a connection string. Ralph uses the standard crystal-db connection string format.
require "ralph/backends/sqlite"
# File-based database
Ralph::Database::SqliteBackend.new("sqlite3://./db/development.sqlite3")
# In-memory database (useful for testing)
Ralph::Database::SqliteBackend.new("sqlite3::memory:")
WAL Mode¶
SQLite supports Write-Ahead Logging (WAL) mode, which improves concurrency by allowing readers to proceed while a write is in progress. This is especially beneficial for production applications with concurrent requests.
# Enable WAL mode for better concurrency
Ralph::Database::SqliteBackend.new("sqlite3://./db/production.sqlite3", wal_mode: true)
# With custom busy timeout (milliseconds)
Ralph::Database::SqliteBackend.new("sqlite3://./db/production.sqlite3", wal_mode: true, busy_timeout: 10000)
When to use WAL mode: - Production environments with concurrent reads and writes - Applications requiring better read/write performance - Multi-threaded web servers
Trade-offs:
- Creates additional files (.sqlite3-wal, .sqlite3-shm)
- Not supported for in-memory databases
- Slightly different file locking behavior
Default behavior: Without wal_mode: true, Ralph uses a mutex to serialize all write operations from the application, which prevents "database is locked" errors but limits write throughput.
PostgresBackend¶
The PostgresBackend allows you to connect to a PostgreSQL database.
require "ralph/backends/postgres"
# Standard connection string
Ralph::Database::PostgresBackend.new("postgres://user:pass@localhost:5432/my_database")
# Using Unix sockets
Ralph::Database::PostgresBackend.new("postgres://user@localhost/my_database?host=/var/run/postgresql")
Environment-Specific Configuration¶
For real-world applications, you'll likely want different configurations for different environments (development, testing, production). A common pattern in Crystal applications is to use environment variables.
Environment Variables¶
Ralph's CLI and backends respect several environment variables for database configuration. They are checked in the following order:
DATABASE_URL- General database URLPOSTGRES_URL- PostgreSQL specific URLSQLITE_URL- SQLite specific URL
Configuration Example¶
Ralph.configure do |config|
db_url = ENV["DATABASE_URL"]? || ENV["SQLITE_URL"]? || "sqlite3://./db/development.sqlite3"
if db_url.starts_with?("postgres")
require "ralph/backends/postgres"
config.database = Ralph::Database::PostgresBackend.new(db_url)
else
require "ralph/backends/sqlite"
config.database = Ralph::Database::SqliteBackend.new(db_url)
end
end
CLI Environment¶
The Ralph CLI also respects the RALPH_ENV environment variable. By default, it looks for a database at ./db/development.sqlite3, but if RALPH_ENV is set to production, it will look for ./db/production.sqlite3.
Testing Configuration¶
When writing tests, it's often best to use an in-memory database to ensure tests are fast and isolated.
# spec/spec_helper.cr
require "spec"
require "../src/ralph"
Ralph.configure do |config|
config.database = Ralph::Database::SqliteBackend.new("sqlite3::memory:")
end
# Optional: Run migrations for the in-memory database
Ralph::Migrations::Migrator.new(Ralph.database, "./db/migrations").migrate
Manual Access to Settings¶
You can also access and modify settings directly through Ralph.settings:
However, using the Ralph.configure block is recommended for better readability and initialization order.