{"id":13484043,"url":"https://github.com/amatsuda/motorhead","last_synced_at":"2025-04-06T04:13:13.109Z","repository":{"id":56884610,"uuid":"44722022","full_name":"amatsuda/motorhead","owner":"amatsuda","description":"A Rails Engine framework that helps safe and rapid feature prototyping","archived":false,"fork":false,"pushed_at":"2017-04-28T14:55:48.000Z","size":132,"stargazers_count":181,"open_issues_count":0,"forks_count":8,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-30T03:06:44.195Z","etag":null,"topics":["ab-testing","engine","prototyping","rails"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amatsuda.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-22T04:25:15.000Z","updated_at":"2023-07-01T14:28:30.000Z","dependencies_parsed_at":"2022-08-20T17:40:38.933Z","dependency_job_id":null,"html_url":"https://github.com/amatsuda/motorhead","commit_stats":null,"previous_names":["amatsuda/wanko"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amatsuda%2Fmotorhead","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amatsuda%2Fmotorhead/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amatsuda%2Fmotorhead/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amatsuda%2Fmotorhead/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amatsuda","download_url":"https://codeload.github.com/amatsuda/motorhead/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430874,"owners_count":20937874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ab-testing","engine","prototyping","rails"],"created_at":"2024-07-31T17:01:18.522Z","updated_at":"2025-04-06T04:13:12.914Z","avatar_url":"https://github.com/amatsuda.png","language":"Ruby","funding_links":[],"categories":["Ruby","Feature Flippers and A/B Testing"],"sub_categories":[],"readme":"# Motorhead\n\nMotorhead is a prototyping framework for Rails.\nIt's something akin to \"feature toggle\".\nIt can be used for \"A/B testing\" as well.\nBut essentially, the main purpose of this framework is to provide a way to rapidly and safely deliver new features to the production environment.\n\n\n## Installation\n\nBundle into your Rails app.\n\n\n## Features\n\n### Isolated Engine\n\nMotorhead helps you mounting specially creafted Isolated Engines onto the main Rails app.\nAn engine can contain whole MVC components, which means that you can encapsulate everything that are needed for your new feature under one single directory.\nThis helps your team creating multiple new features simultaneously without causing code conflict.\n\n### Conditional Execution\n\nEach Motorhead engine can be configured to be enabled/disabled.\nThe condition is not just a flag but can be a Ruby Proc which will be dynamically evaluated on each request in the controller context.\n\n### Error-proof\n\nIf any RuntimeError happens inside an engine on the production environment, Motorhead absorbs the error and executes the appropriate fallback code so that the end users would never even notice the occurrence of the error.\n\n### Extending Action Methods in the Main App\n\nMotorhead provides an interface to override the main app's controller actions.\n\n### Partially Extending Views in the Main App\n\nMotorhead provides a hook to partially overwrite any part of your existing view.\n\n\n## Structure\n\n    main_app\n    ├── Gemfile\n    ├── Gemfile.lock\n    ├── Rakefile\n    ├── app\n    │   ├── assets\n    │   ├── controllers\n    │   ├── engines\n    │   │   ├── my_awesome_new_feature\n    │   │   │   ├── app\n    │   │   │   │   ├── assets\n    │   │   │   │   ├── controllers\n    │   │   │   │   │   └── my_awesome_new_feature\n    │   │   │   │   │       └── welcome_controller.rb\n    │   │   │   │   ├── helpers\n    │   │   │   │   │   └── my_awesome_new_feature\n    │   │   │   │   │       └── welcome_helper.rb\n    │   │   │   │   ├── mailers\n    │   │   │   │   ├── models\n    │   │   │   │   └── views\n    │   │   │   │       ├── layouts\n    │   │   │   │       │   └── my_awesome_new_feature\n    │   │   │   │       │       └── application.html.erb\n    │   │   │   │       └── my_awesome_new_feature\n    │   │   │   │           └── welcome\n    │   │   │   ├── config\n    │   │   │   │   └── routes.rb\n    │   │   │   ├── lib\n    │   │   │   │   ├── my_awesome_new_feature\n    │   │   │   │   │   └── engine.rb\n    │   │   │   │   ├── my_awesome_new_feature.rb\n    │   │   │   │   └── tasks\n    │   │   │   ├── my_awesome_new_feature.gemspec\n    │   │   │   └── test\n    │   │   └── yet_another_new_feature\n    │   │       ├── app\n    │   │       ...\n    │   ├── helpers\n    │   ├── mailers\n    │   ├── models\n    │   └── views\n    ├── bin\n    ├── config\n    ├── db\n    ...\n\n\n## Components\n\n### lib/ENGINE\\_NAME/engine.rb\n\nPut `active_if` directive inside the Engine class. The whole engine will only be executed if the block is evaluated to be truthy on runtime.\n\nExample:\n\n```ruby\n# app/engines/my_awesome_new_feature/config/routes.rb\nmodule MyAwesomeNewFeature\n  class Engine \u003c ::Rails::Engine\n    include Motorhead::Engine\n\n    # this whole engine will be executed only when logged in as admin users\n    active_if { current_user.admin? }\n  end\nend\n```\n\nYou can configure a path to mount the Engine via `mount_at` directive. This value is defaulted to \"/\", which means the Engine routes will be mixed into the main app's routes.\n\nExample:\n\n```ruby\n# app/engines/my_awesome_new_feature/config/routes.rb\nmodule MyAwesomeNewFeature\n  class Engine \u003c ::Rails::Engine\n    include Motorhead::Engine\n\n    # all routes inside this Engine will be prefixed by \"/harley\"\n    mount_at 'harley'\n  end\nend\n```\n\n### routes.rb\n\nAll routes in engines' routes.rb will be automatically prepended to the main app's Routes.\n\n\n### Controllers\n\nControllers can be a normal Engine controller.\nOr, you can craft a controller class inheriting a controller that exists in the main app, and overriding some action methods.\nFrom inside the actions in engines, you can call the main app's action via `super`.\n\nExample:\n\n```ruby\n# app/engines/my_awesome_new_feature/app/controllers/my_awesome_new_feature/welcome_controller.rb\nclass MyAwesomeNewFeature::WelcomeController \u003c ::WelcomeController\n  include Motorhead::Controller\n\n  def index\n    # invoking the main app's action first\n    super\n\n    # adding some more business logic\n    @notifications = Notification.for current_user\n  end\nend\n```\n\n\n### Views\n\nWhen an engine renders the views, it looks up app/views/ENGINE\\_NAME/ directory first, then the main app's view directory next. This way you can overwrite views per template/partial file.\nAlso, Motorhead adds new `:engine` option to `render` method, which enables you to explicitly inject a piece of HTML from an engine into any place of the app.\n`render :engine` takes an `ENGINE_NAME/view_path' parameter.\n\nExample:\n\n```haml\n# app/engines/my_awesome_new_feature/app/views/my_awesome_new_feature/welcome/_index.html.haml\n.new_feature\n  Some contents for new feature\n\n# app/views/welcome/index.html.haml\n= render engine: 'my_awesome_new_feature/welcome/index' do\n  Some contents that will be shown by default\n```\n\n\n## Generators\n\nMotorhead provides some handy code generators.\n\n### Generating an engine\n\n```\n% rails g motorhead ENGINE_NAME\n```\n\nExample:\n\n```\n% rails g motorhead my_awesome_new_feature\n```\n\n  This generates a motorhead Engine in\n  ~/app/engines/my\\_awesome\\_new\\_feature/ directory.\n\n### Generating an engine + a controller extension that extends an existing controller\n\n\n```\n% rails g motorhead ENGINE_NAME CONTROLLER_NAME [action action] [options]\n```\n\nExample:\n\n```\n% rails g motorhead my_awesome_new_feature welcome index\n```\n\n  This generates a motorhead Engine in ~/app/engines/my\\_awesome\\_new\\_feature/ directory.  Plus, a controller that extends WelcomeController and implements index action inside the Engine.\n\n\n## Managing Engines\n\nMotorhead includes a tiny admin console Engine call \"RoadCrew\" through which you can easily enable/disable each mounted Engine.\nTo use this, require `'motorhead/road_crew'` when bundling motorhead gem in your Gemfile:\n\n```ruby\n# Gemfile\ngem 'motorhead', path: '~/src/motorhead', require: ['motorhead', 'motorhead/road_crew']\n```\n\nthen render the `road_crew/button` Engine partial to put a button inside somewhere in your view (usually in the header or footer?):\n\n```erb\n# app/views/layouts/application.html.erb\n\u003c%= render engine: 'road_crew/button' %\u003e\n```\n\nYou might also want to configure the RoadCrew Engine's `active_if` directive for security.\n\n```ruby\n# config/initializers/mh_road_crew.rb\nRoadCrew::Engine.active_if { current_user.admin? }\n```\n\n\n\n\n\n\n## Contributing\n\nPull requests are welcome on GitHub at https://github.com/amatsuda/motorhead.\n\n\n## Todo\n\n* Better generator\n\n* Model extension\n\n* Documentation\n\n\n## Special Thanks\n\nThis product is deeply inspired by [Chanko](http://cookpad.github.io/chanko/).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famatsuda%2Fmotorhead","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famatsuda%2Fmotorhead","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famatsuda%2Fmotorhead/lists"}