Creating a Rails Engine Plugin Gem Gizmo in Rails 4

rails

Ruby on Rails supports the ability to be extended through the use of libraries, which are packaged as ‘gems’ and included in your ‘Gemfile’. This much is well known. Rails also has, depending on the version, engines and/or plugins. Engines are ‘subapplications’ that can have their own models, controllers, and views 1 Plugins are gems that extend the core Rails classes - before engines came along, if you wanted to add views and controllers to a gem, you’d make it a plugin.

So, how do we make a gem that can extend rails applications with views, controllers, and the rest? What we want to do is create an ‘engine’ packaged as a ‘gem’.

I’ve found that the documentation on this process isn’t quite as good as the documentation for the rest of the rails API. Perhaps because creating an engine is a little bit more of an advanced topic, and much of the documentation for Rails is of the ‘blog in fifteen minutes variety’ 2.

In Rails 3.1+ we should be able to create the skeleton of a plugin (actually an engine) with the following command 3:

1
rails plugin new engine_name --full

Helpfully, this command to create your engine skeleton will tell you that validations have failed: FIXME or TODO is not an author. This is referring to the required fields in your brand new engine_name/engine_name.gemspec file, which asks for an author and author email. You can edit the engine_name/engine_name.gemspec file to update this information now. You’ll have to update all the lines that include TODO or FIXME: s.authors, s.email, s.homepage, s.summary, and s.description.

Your new rails engine is a gem. So, it can be pushed to rubygems.org to be shared with the entire world. Which is fantastic! Unless you’re working on client code, or patented code, or otherwise can’t share. If that’s the case, you should be able to add the following line: to your .gemspec:

1
2
3
4
Gem::Specification.new 'engine_name', '1.0' do |s|
  # ...
  s.metadata['allowed_push_host'] = ""
end

This will disable pushes 4. You can still work on your gem locally. If you later decide you need to make your gem available to some servers and collaborators but no the entire world, consider a service like Gemfury

You can still push the gem to a git repository, of course. To do so, follow the usual steps: git init ., git add -A, git commit, git remote add, git push, and so on. If you do this, you can actually install the gem from other machines that have read access to the git repository, though it might be a tad slower than installing directly from a gem server.

If you do push your new engine to a git repository, you can install it in a rails application you control by adding the following line to your Gemfile:

1
gem 'engine_name', git: 'git://your_git_server.tld/git_path/engine_name.git'

Don’t forget to run bundle install.

Now you’re ready to get coding on your rails engine distributed as a gem. Happy coding!


  1. See This Stack Overflow Post

  2. Not that there’s anything wrong with that; it is part of why I got into Rails in the first place.

  3. See section “Use with 3.0 Only” in josevalim/enginex

  4. Serving your Own Gems


I'm looking for better ways to build software businesses. Find out if I find something.