Rails HMVC

Gem Version Ruby Style Guide

Your Rails controllers are doing too much. Validation logic mixed with business rules. Database queries sitting next to HTTP responses. Fat models or fat controllers — pick your poison.

Rails HMVC fixes this by introducing two new layers — Form and Operation — between the controller and model, each with a single clear responsibility. One command generates the entire structure.

The Problem

As Rails apps grow, MVC breaks down:

  • Controllers become dumping grounds — validation, business logic, authorization, and response formatting all in one file
  • Models turn into god objects — hundreds of lines mixing associations, scopes, callbacks, and business rules
  • No consistent structure across the team — every developer organizes differently
  • Testing becomes painful — you can't test business logic without booting the entire HTTP stack
  • API versioning is an afterthought — breaking changes sneak into production

The Solution

Rails HMVC enforces separation of concerns through 5 layers, each doing exactly one thing:

Layer Responsibility
Controller HTTP only — receive request, return response
Form Validate and transform input params
Operation Execute business logic (the "what happens")
Serializer Format JSON output
Error Standardized error handling

One generator creates everything:

rails g rails_hmvc:controller v1/users --type=api

This generates: 1 controller, 5 operations, 2 forms — all wired up, all following the same pattern.

Quick Start

# Gemfile
gem 'rails_hmvc'
bundle install

# Initialize HMVC structure
rails g rails_hmvc:init --type=api

# Generate your first resource
rails g rails_hmvc:controller v1/users --type=api

That's it. Your app now has:

  • Base classes (MainController, MainForm, MainOperation, MainSerializer)
  • Error handling (Errorable concern with standardized JSON errors)
  • Render helpers (render_collection, render_resource)
  • A versioned, structured component tree under app/

How It Works

HTTP Request
    
    
Controller ──► Form (validate input)
                  
                   raise Errors::ResourceError if invalid
    
    └────────► Operation (business logic)
                   
                   
                 Model (database)
                   
                   
              Serializer (format JSON)
                   
                   
             HTTP Response

The controller never touches the database. Forms never run business logic. Operations never format responses. Each piece is testable in isolation.

Requirements

  • Ruby >= 2.7.0
  • Rails >= 6.1.0

Development

All development happens inside Docker — do not run Ruby on the host.

docker compose up -d                # start container (stays alive)
docker compose exec dev bash        # exec into container to work

# Inside container:
bundle exec rake                    # tests + rubocop (same as CI)
bundle exec rspec                   # tests only
COVERAGE=true bundle exec rspec     # 100% coverage check
gem build rails_hmvc.gemspec        # build .gem

See CONTRIBUTING.md for details.

Documentation

English Tiếng Việt 日本語
Getting Started en vi ja
Architecture en vi ja
Generators en vi ja
Components en vi ja
Testing en vi ja

License

The gem is available as open source under the terms of the MIT License.