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
他にも思いついたら追記していきます。
関連する記事
- 久しぶりにRailsで開発して感じたこと
- 【Rails】リロード時に特定の処理を実行する
- 【実践】Railsにて検索結果をそのままCSV出力する(やや手抜きで)
- 【Rails 5】ヘルパーを使用しているactive_decoratorをrspecでテストする
- AngularJS + Railsで国際化(i18n)