Rails用のgemを作成する手順 (Rails 4.0以降)


railsで使用されることを前提としたgemの開発手順です。いつもコマンドとかオプションを忘れてしまうので、備忘録として記述しておきます。

ディレクトリ作成

まずはrails pluginコマンドでgem開発用ディレクトリを作成します。

📄dummyのapplication.js
$ bundle exec rails plugin new <プラグイン名> --full --skip-bundle
ヘルプが見たい場合は
$ bundle exec rails plugin new --help

--skip-bundleがないと、bundle installが走ってしまいます。パス指定せずにインストールすると、グローバル環境を壊してしまう可能性があるので、各開発ディレクトリにインストールしてます。

$ cd <プラグイン名>
$ bundle install --path=vendor/bundle

あとは直下のプラグイン名.gemspecファイルを編集して開発を始められます。

テスト用railsアプリ

testディレクトリ以下にdummyというディレクトリが作成されています。通常のrailsアプリなので、こいつにプラグインgemを読み込んでテストすることになります。

このテスト用アプリ(dummy)は、以下のようにして起動することができます。

$ cd test/dummy
$ bin/rails s

プラグインgemのJavascriptを読み込む

普通に読み込むことができます。例えばプラグインディレクトリ/app/assets/javascripts/hoge.jsというJavascriptを作成し、この内容をdummyに読み込みたい場合は、test/dummy/app/assets/javascripts/application.js

//= require hoge
//= require_tree .

てな感じで書いてやればいいです。

ActionController::Baseを拡張する

プラグインgemを読み込むだけで、他に何もしなくても、すべてのコントローラで使用できるメソッドを追加したい場合があります。そういった場合はActionController::Baseを拡張してやればいいです。

ActiveSupport.on_loadを使用すれば、モジュールの読み込み処理をフックすることができます。そのモジュールが読み込まれたタイミング、もしくは既に読み込まれていれば即時に、特定の処理を実行できます。

プラグインディレクトリ/lib/プラグイン名/engine.rbを編集します。例として、awesome_gemという名前のgemを開発中で、NiceModuleというナイスなモジュールをインクルードするとします。

📄engine.rb
require 'awesome_gem/nice_module' # プラグインディレクトリ/lib/awesome_gem/nice_module.rb

module AwesomeGem
  class Engine < ::Rails::Engine
    initializer 'awesome_gem.action_controller_extension' do
      ActiveSupport.on_load :action_controller do
        # p self #=> ActionController::Base
        include AwesomeGem::NiceModule
      end
    end
  end
end

railsのApplicationControllerはActionController::Baseを継承してますので、NiceModule内のメソッドは、すべてのコントローラで使用できるというわけです。

Form用ヘルパーを拡張する

ActionView::Baseや、ActionView::Helpers::FormBuilderなどを拡張する例です。先ほどのActionController::Baseを拡張する場合とほぼ同じです。

📄engine.rb
require 'awesome_gem/helpers' # プラグインディレクトリ/lib/awesome_gem/helpers.rb

module AwesomeGem
  class Engine < ::Rails::Engine
    initializer 'awesome_gem.action_view_extension' do
      ActiveSupport.on_load :action_view do
        # p self #=> ActionView::Base
        include AwesomeGem::Helpers::FormTagHelper
        ActionView::Helpers::FormBuilder.class_eval do
          include AwesomeGem::Helpers::FormHelper
        end
      end
    end
  end
end

これでビュー内からlink_to_awesomeとか、f.awesome_fieldとか書けるようになるわけです。ちなみに、上記例のhelpers.rbは次のように記述すればいいかと思います。

📄helpers.rb
module AwesomGem
  module Helpers
    extend ActiveSupport::Autoload

    autoload :FormTagHelper
    autoload :FormHelper
    include FormTagHelper
    include FormHelper
  end
end

こうしておけば、Helpersというネームスペースの基に、各Moduleを別ファイルで管理できます。

Gemを作成する

gemspecファイル内をきちんと記述してから、次のコマンドを実行します。

📄Gemfile
$ gem build with_popup.gemspec

rake buildでもできるんですが、gem buildの方が警告を発してくれるので便利です。

Gemをテストする

作成したgemを他のプロジェクトからちゃんと使えるのかというテストです。他のプロジェクトのGemfileに次のように記述します。

gem 'awesome_gem', '0.0.1', path: '/path/to/directory_of_awesome_gem.gemspec'

最初pathに指定するのはできあがったgemファイルへのパスだと思ってました。しかし正解は、gem開発ディレクトリのルート(gemspecがあるディレクトリ)へのパスです。また、バージョンは指定する必要があります。

Gemをリリースする

rubygemsにアカウントさえあれば、コマンド一発で登録できます。

$ gem push awesome_gem-0.0.1.gem

 

他にも思いついたら追記していきます。

関連する記事


コメントする

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください