0.0
There's a lot of open issues
Organizes and sets up the architecture of micro-applications within a Rails application, enabling segregation, management, and isolation of functionalities, thereby supporting independent development, testing, and maintenance.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 7.0, < 9.0
 Project Readme

Feature Pack Gem

Gem Version License: MIT

Feature Pack organizes and sets up the architecture of micro-applications within a Ruby on Rails application, enabling the segregation of code, management, and isolation of functionalities. Features can be developed, tested, and maintained independently of each other.

Installation

Add this line to your application's Gemfile:

gem 'feature_pack'

And then execute:

bundle install

Setup

Add to your config/application.rb:

# After Bundler.require
require 'feature_pack'
FeaturePack.setup

Concepts

Groups

Groups are collections of related features. They provide:

  • Shared layouts and partials
  • Common base controller functionality
  • Namespace organization
  • Shared JavaScript modules

Features

Features are individual functionalities within a group. They provide:

  • Independent controllers and views
  • Isolated routes
  • Feature-specific JavaScript
  • Complete MVC structure

Usage

Creating a New Group

rails generate feature_pack:add_group human_resources

This creates the following structure:

app/feature_packs/
└── group_YYMMDD_human_resources/
    └── _group_space/
        ├── controller.rb
        ├── manifest.yaml
        ├── routes.rb
        ├── javascript/
        └── views/
            ├── index.html.slim
            └── partials/
                ├── _header.html.slim
                └── _footer.html.slim

Creating a New Feature

rails generate feature_pack:add_feature human_resources/employees

This creates:

app/feature_packs/
└── group_YYMMDD_human_resources/
    └── feature_YYMMDD_employees/
        ├── controller.rb
        ├── manifest.yaml
        ├── routes.rb
        ├── doc/
        │   └── readme.md
        ├── javascript/
        ├── queries/
        └── views/
            ├── index.html.slim
            └── partials/
                ├── _header.html.slim
                └── _footer.html.slim

Code Structure

Naming Convention

Groups

Format: group_<id>_<name>

  • group_ - Required prefix
  • <id> - Unique identifier (typically YYMMDD format)
  • <name> - Group name in snake_case

Example: group_241209_human_resources

Features

Format: feature_<id>_<name>

  • feature_ - Required prefix
  • <id> - Unique identifier (typically YYMMDD format)
  • <name> - Feature name in snake_case

Example: feature_241209_employees

Directory Structure

Group Space (_group_space)

Contains group-level resources:

  • controller.rb - Base controller for all features in the group
  • manifest.yaml - Group configuration
  • routes.rb - Group-level routes
  • views/ - Shared views and layouts
  • javascript/ - Shared JavaScript modules

Feature Directory

Contains feature-specific resources:

  • controller.rb - Feature controller
  • manifest.yaml - Feature configuration
  • routes.rb - Feature routes
  • views/ - Feature views
  • javascript/ - Feature-specific JavaScript
  • queries/ - Database queries
  • doc/ - Feature documentation

Controllers

Group Controller

class FeaturePack::HumanResourcesController < FeaturePack::GroupController
  # Group-wide functionality
end

Feature Controller

class FeaturePack::HumanResources::EmployeesController < FeaturePack::HumanResourcesController
  def index
    # Feature-specific logic
  end
end

Generated feature controllers inherit their group's controller, so group callbacks (authentication, authorization, etc.) apply to every feature. The setup callback resolves the context from the routed path (feature_pack/<group>/<feature>): when the second segment is a registered feature the request receives @group and @feature and uses the feature's views; otherwise it receives @group and the group's views. No extra declaration is needed in feature controllers.

Feature controllers that don't need a group controller can still inherit FeaturePack::Controller, which requires the path to name a registered feature.

API-only features can inherit FeaturePack::API::Controller (an ActionController::API subclass with no view setup). Load feature_pack/api/controller.rb in config.after_initialize alongside the other base controllers (see SETUP.md).

The private hooks set_view_lookup_context_prefix and set_layout_paths can be overridden in a group controller and apply to both group and feature requests.

Migrating from 0.10.x

  • To share group callbacks, change a feature controller's superclass from FeaturePack::Controller to FeaturePack::<Group>Controller.
  • __after_initialize.rb hooks are no longer loaded. Move that code to a Rails initializer or to the group/feature controller and delete the hook files. Leftover files are ignored by Zeitwerk, but they are dead code.
  • FeaturePack.setup now fails when app/feature_packs does not exist. Create the directory, or call FeaturePack.setup(require_features_path: false) to boot with no groups (a warning is logged).

Routes

Routes are automatically configured based on manifest files:

# Group manifest.yaml
url: /hr
name: Human Resources

# Feature manifest.yaml
url: /employees
name: Employees Management

This generates routes like:

  • /hr - Group index
  • /hr/employees - Feature index

Helpers

Path Helpers

# Group path
feature_pack_group_path(:human_resources)
# => "/hr"

# Feature path
feature_pack_path(:human_resources, :employees)
# => "/hr/employees"

# With parameters
feature_pack_path(:human_resources, :employees, id: 1)
# => "/hr/employees?id=1"

Controller Variables

Available in controllers and views:

  • @group - Current group object
  • @feature - Current feature object (not available in group controller)

View Hierarchy

Views are resolved in the following order:

  1. Feature-specific views
  2. Group-shared views
  3. Application default views

Partials

Header and footer partials follow a fallback pattern:

  1. Feature's views/partials/_header.html.slim
  2. Group's views/partials/_header.html.slim
  3. Application's default header

JavaScript Integration

JavaScript files are automatically discovered and can be referenced:

# In views
javascript_include_tag @group.javascript_module('shared')
javascript_include_tag @feature.javascript_module('employees')

Advanced Configuration

Manifest Files

Group manifest (_group_space/manifest.yaml):

url: /hr
name: Human Resources
const_aliases:
  - employee_model: Employee
  - department_model: Department

Feature manifest:

url: /employees
name: Employees Management
const_aliases:
  - service: EmployeeService

Const Aliases

Access aliased constants:

# In controllers
@group.employee_model  # => Employee
@feature.service       # => FeaturePack::HumanResources::Employees::EmployeeService

Best Practices

  1. Group Organization: Group related features that share common functionality
  2. Naming: Use descriptive snake_case names for groups and features
  3. Isolation: Keep features independent and loosely coupled
  4. Shared Resources: Place common code in group space
  5. Documentation: Document each feature in its doc/readme.md

Troubleshooting

Common Issues

  1. Group/Feature Not Found

    • Ensure proper naming convention
    • Run FeaturePack.setup after adding new groups/features
    • Check manifest files exist
  2. Routes Not Working

    • Verify manifest.yaml has correct URL configuration
    • Check routes.rb files exist
    • Restart Rails server after changes
  3. Views Not Rendering

    • Check view file extensions (.html.slim, .html.erb, etc.)
    • Verify view paths in controller
    • Check for typos in view names

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

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

Author

Gedean Dias - gedean.dias@gmail.com

Links

Tests

bundle install
bundle exec rspec

The suite covers discovery, setup rollback, first-time generation, duplicate protection, inherited authorization, and Rails request rendering using ERB fixtures.