Skip to content
kranzkyPublic

About

Extends ActiveRecord with an Entity–Component–System persistence architecture inspired by Flecs.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ECS Rails

An Entity–Component–System reimagining of ActiveRecord that stays idiomatic to Ruby on Rails.

Published as ecs_on_rails (0.3.0), the zero-migrations release. After rails g ecs_rails:install and one db:migrate, entities, labelled slots, relationships, markers and systems are plain Ruby: the catalogue ships the components (ADR-0018) and one shared table holds every relationship (ADR-0017). Tested on real PostgreSQL across Rails 7.1–8.1. The companion bulletin board and marketplace run at ecs-rails.kranzky.com. Upgrading from 0.2? See the changelog. Earlier: the v0.1 retrospective and "Composing Rails".

The idea

Replace one-table-per-model with one-table-per-component. An entity is a lightweight identity row. All state and behaviour live in small, reusable components composed onto it.

class User < ApplicationEntity
  component Name
  component Email
  component Image, prefix: :avatar
end
user = User.create!            # one row in `entities`, no component rows
user.email                     # => #<Email> — virtual, not persisted
user.email_address = "a@b.com" # delegated to the Email component, prefixed
user.save!                     # now `emails` gets a row

user.name.initials            # behaviour lives on the component
Email.where(verified: false)   # components are queried directly

User.create!(name_given: "Ada", email_address: "a@b.com")  # flat keys route too

Components are lazy: reading an absent component returns virtual defaults; only a value differing from its default needs a new row. The first read may query. Components are shared by type: a Counter can serve a Post's likes or a Product's stock in different labelled slots.

Systems are plain Ruby objects operating on components across entity types. Follow the executable contacts quickstart to install, compose, query, run a system and render a page. For the full sample application, use the demo setup.

Layout

docs/ The specification. Architecture, ADRs, RFCs, backlog.
gem/ The ecs_rails gem.
demo/ A bulletin board and marketplace built entirely from the catalogue — one migration in db/migrate — via path: "../gem" during a build; pinned to the published gem at each release.

The demo is built alongside the gem, not after it. If a feature feels awkward in the demo, that's the signal the API is wrong. See PROCESS.md.

Names

ecs_rails everywhere except the Gemfile — see ADR-0007.

GitHub repo RubyGems gem Ruby module require
ecs_rails ecs_on_rails EcsRails ecs_rails
gem "ecs_on_rails"   # Gemfile — the packaging name
require "ecs_rails"  # everything else

Only the published gem name differs. RubyGems collapses -, _ and case when comparing names, so ecs-rails, ecs_rails and ecsrails are one name — and it belongs to an unrelated, still-maintained gem. ecs_on_rails keeps the rails keyword without the rails- prefix that convention reserves for Rails Core Team gems.

Start here

Start with the quickstart or demo guide. Read the source walkthrough when you want to follow the implementation.

The architecture, ADRs and RFCs provide the invariants, design decisions and feature contracts.

Worth knowing up front, because the honest version is more useful than the pitch:

  • ADR-0002 — entity identity still uses a discriminator column. What ECS Rails eliminates is STI for state and behaviour, not for identity.
  • ADR-0003 — a component can't require its own presence. That's the entity's business.
  • ADR-0005 — one component instance per entity per slot. Labels allow the same type to be reused.

Development

Requires Ruby >= 3.2 and PostgreSQL.

cd gem
createdb ecs_rails_test
bundle install
bundle exec rspec

Licence

MIT. See LICENSE.

About

Extends ActiveRecord with an Entity–Component–System persistence architecture inspired by Flecs.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages