Installation
Get RailsPress running in your Rails 8 application in under 5 minutes.
Requirements
- Ruby 3.3+
- Rails 8.1.3.1+ (includes the Active Storage variant security fix)
- PostgreSQL, MySQL, or SQLite
- ActionText (comes with Rails)
- Active Storage (required for post images and CMS image elements)
Quick Start
The live demo is a full RailsPress installation you can click through before you install anything.
1. Add to Gemfile
gem "railspress-engine"
2. Install and Migrate
Install ActionText and Active Storage first if your app does not already have them:
$ rails action_text:install
$ rails active_storage:install
$ rails db:migrate
Then install RailsPress:
$ bundle install
$ rails generate railspress:install
$ rails db:migrate
RailsPress now handles Lexxy wiring internally. You do not need to add a manual pin "lexxy" to your host config/importmap.rb for standard installs.
The generated config/initializers/railspress.rb ships with every feature disabled and documented as commented-out toggles, so you can uncomment the ones you need. See Configuring for the full menu.
4. Set Up Image Processing (Optional)
If you plan to use resized header images or pass a variant: option to rp_featured_image_url, Active Storage needs an image processor. RailsPress ships image_processing as a runtime dependency, but the processor gem and its native library remain deployment choices. Add one to your Gemfile:
# Recommended for Rails 8.1.3.1+ applications
gem "ruby-vips", "~> 2.2", ">= 2.2.1"
# Or use ImageMagick instead
# gem "mini_magick", "~> 5.0"
Then install the matching system library (libvips 8.13+ for ruby-vips, or ImageMagick for mini_magick) in every environment that generates variants. Displaying original header images works without this. See Active Storage & Image Variants for full details.
Mount the Engine
Add to your config/routes.rb:
Rails.application.routes.draw do
mount Railspress::Engine => "/railspress", as: :railspress
end
The admin interface will be available at /railspress/admin.
Admin Paths
| Path | Description |
|---|---|
/railspress/admin |
Dashboard |
/railspress/admin/posts |
Manage posts |
/railspress/admin/categories |
Manage categories |
/railspress/admin/tags |
Manage tags |
/railspress/admin/api_keys |
Agents & API key management (when enable_api is enabled) |
/railspress/admin/content_groups |
Manage CMS content groups (when enable_cms is enabled) |
/railspress/admin/content_elements |
Manage CMS content elements (when enable_cms is enabled) |
/railspress/admin/cms_transfer |
CMS content import/export (when enable_cms is enabled) |
Models Reference
Railspress::Post
| Attribute | Type | Description |
|---|---|---|
title |
string | Post title (required) |
slug |
string | URL-friendly identifier (auto-generated) |
content |
rich_text | Post body (ActionText) |
status |
enum | draft or published |
published_at |
datetime | When post was published |
meta_title |
string | SEO title override |
meta_description |
text | SEO description |
category_id |
integer | Optional category |
excerpt |
text | Short summary used in blog listings |
reading_time |
integer | Auto-calculated reading time in minutes |
author_id |
integer | References the configured author model |
header_image |
attachment | Featured image for the post |
Associations:
belongs_to :category(optional)has_many :tags(through taggings)has_rich_text :contentbelongs_to :author, polymorphic: true(when authors are enabled)
Scopes:
published- Posts with status "published" and apublished_atdate setdrafts- Posts with status "draft"ordered- Bypublished_atdescending (published first, then created_at)recent- Last 10 posts (ordered)by_author(author)- Filter posts by author (when authors are enabled)rp_search(query)- Case-insensitive, adapter-aware substring search on titlerp_page(page_number)- RailsPress's dependency-free paginationrp_per_page_count- Resolved RailsPress page size (defaults to 20)by_category(category_or_id)- Filter by category object or idby_status(status)- Filter by status enum valuesorted_by(column, direction)- Multi-column sorting
As of RailsPress 1.4.3, engine-owned search and pagination live under the rp_ prefix so they never collide with your app's own search scopes or pagination gem. The generic search, page, and per_page_count names remain as deprecated compatibility methods through RailsPress 1.x. See Upgrading for details.
Railspress::Category
| Attribute | Type | Description |
|---|---|---|
name |
string | Category name (required, unique) |
slug |
string | URL-friendly identifier (auto-generated) |
Railspress::Tag
| Attribute | Type | Description |
|---|---|---|
name |
string | Tag name (required, unique, lowercase) |
slug |
string | URL-friendly identifier (auto-generated) |
Railspress::ApiKey
Available when enable_api is enabled. Represents long-lived bearer tokens for API access.
| Attribute | Type | Description |
|---|---|---|
name |
string | Human-readable key label shown in admin |
token_prefix |
string | Short key prefix displayed for audits |
expires_at |
datetime | Optional expiration timestamp |
last_used_at |
datetime | Last successful API usage timestamp |
revoked_at |
datetime | Revocation timestamp (if revoked) |
Railspress::AgentBootstrapKey
Available when enable_api is enabled. Represents short-lived one-time tokens used to mint API keys for agent onboarding.
| Attribute | Type | Description |
|---|---|---|
name |
string | Bootstrap key label shown in admin |
token_prefix |
string | Short key prefix displayed in admin tables |
expires_at |
datetime | Expiration (defaults to 1 hour) |
used_at |
datetime | When the token was exchanged |
revoked_at |
datetime | Revocation timestamp (if revoked before use) |
For endpoint-level API details, see the API reference docs.