Gems, Plugins, Engines, and Mountable Engines: 4 ways to make a Gem.
July 1, 2021
Every time I go to make a new ruby gem, I need to look up the specific way to get started. Hereās a summary of the different options.
Ā
Ruby Gem
bundle gem <name>
When to use it
Your gem can be used outside of Rails.
Why itās a good fit
- Does not put any rails dependencies in the gemspec
- Gem code lives in lib/ and must be explicitly required
More info
https://bundler.io/guides/creating_gem.html
Ā
Rails Plugin
rails plugin new <name>
When to use it
Your gem is intended to be used by a Rails application as model-level code. You want to be able to test your gem as if it were running in a rails app.
Why itās a good fit
- Puts rails dependencies in the gemspec
- Provides a simple rails application for testing in test/dummy
- Provides a railtie for integrating with rails internals or running code at application startup
- Gem code lives in lib/ and must be explicitly required
More info
https://guides.rubyonrails.org/plugins.html
Ā
Rails Engine
rails plugin new <name> --full
When to use it
Your gem includes models, views, controllers, helpers, assets, etc that you want to make available to a rails app as if that code were written directly in the application. You want to allow the application to override your gemās files.
Why itās a good fit
- Puts rails dependencies in the gemspec
- Provides a simple rails application for testing in test/dummy
- Provides an app/ folder with the standard rails subfolders (models, controllers, etc). Code in this folder will be autoloaded just like it were written directly in the including application
- If the including rails application and your gem have files at the same path within the app/ folder, the including applicationās file will take precedence (handy for local customization)
- You can still write code in lib/ and explicitly require it
More info
https://guides.rubyonrails.org/engines.html
Ā
Rails Mountable Engine
rails plugin new <name> --mountable
When to use it
Your gem is a complete rails application that other applications can include and mount at the route of their choosing. You want to avoid name collisions with the including rails app.
Why itās a good fit
- Puts rails dependencies in the gemspec
- Provides a simple rails application for testing in test/dummy
- Includes an app/ folder with the standard rails subfolders (models, controllers, etc) where you can write your engineās application code
- Includes files needed for a standalone mini-application (routes, ApplicationController/Helper, asset manifests)
- Sets up namespace isolation so gem routes, assets, and base classes donāt conflict with the including applicationsā
- You can still write code in lib/ and explicitly require it