Rails Generator and Gem

Recently i created two emberjs-rails projects.(money,food-ntpc). Everytime i have to create a new rails project and add gems(ember-rails,twitter-bootstrap,thin…) repeatedly. Based on DRY principle i try to write a gem to solve trivials.
Finally, my first gem railsone is out and push to RubyGems. There are many Rail proper nouns like Generator,Template,Plugins,Engine. In the beginning it’s very confuse to me but i have solved them luckly :)

How to make gem and generator?

Use bundler to create gem structure. railsone is my gem name.

1
bundle gem railsone

It create structure like below

1
2
3
4
5
6
railsone/lib/
railsone/lib/railsone.rb
railsone/lib/railsone/version.rb
railsone/railsone.gemspec
railsone/Gemfile
railsone/Rakefile

Edit railsone.gemspec. We should finish TODO parts.

railsone.gemspec
1
2
3
4
...
spec.description   = %q{Railsone helps you create emberjs 1.0 with twitter bootstrap 3.0}
spec.summary       = %q{Create emberjs with twitter bootstrap}
...

Then create a file in lib/railsone/generators/install_generator.rb. It’s better to put my custom generator in a generators folder.

railsone.gemspec
1
vim railsone/lib/railsone/generators/install_generator.rb

Next the default auto generated file is in lib/railsone.rb. We should modify it to require my generator file.

railsone.rb
1
2
3
4
5
6
require "railsone/version"
require "railsone/generators/install_generator" # require my custom generator.

module Railsone
  # Your code goes here...
end

Now continue to finish our install_generator.rb

railsone.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require 'rails/generators' # require rails's generator

module Railsone
  module Generators
    class InstallGenerator < ::Rails::Generators::Base
      desc "generator to create emberjs and twitter bootstrap" # description when you type rails g railsone:install --help

      self.source_paths << File.join(File.dirname(__FILE__), '../../../templates') # source_paths is for external files

      def example_cmd
        gem 'ember-rails'
        remove_file 'app/assets/javascripts/application.js'
        copy_file 'application.js', 'app/assets/javascripts/application.js'
        ...
      end
  end
end

Your generator may use external files and they should be searched by source_paths. I create a templates folder to place files. It’s under root folder.

folder_structure
1
2
railsone/lib/
railsone/templates/

Any public method in your generator will be executed automatically. It means example_cmd will be executed when you execute generator.
Directive gem 'ember-rails' means add gem ‘ember-rails’ into Gemfile. All commands can be found in RubyGuides and Thor:Action.
Directive copy_file copy my custom application.js(in templates/application.js) to overwrite project’s application.js(in app/assets/javascripts/application.js).

How to test?

Before push to RubyGems, we should do a minimal testing. Create a new rails project.

1
rails new myrails

Assume your myrails and railsone are in the same folder

1
2
railsone/
myrails/

Add railsone to your myrails’s Gemfile

Gemfile
1
2
3
...
gem 'railsone', path: '../railsone'
...

Execute railsone generator. railsone is our namespace and install is our generator name.

1
2
cd myrails/
rails g railsone:install

Then your will find your myrails Gemfile and application.js are changed.

How to publish?

Push to RubyGems is incrediblely simple. Refer to RubyGems. Don’t forget to create your account first.

1
2
3
4
5
# build your gem
gem build railsone.gemspec

# publish your gem
gem push railsone-0.0.1.gem

Comments