Rails Guides のプラグインの作り方を実行していく俺手順(1)
参照: The Basics of Creating Rails Plugins
上記のドキュメントは現時点で work n progress な状態で(当たり前だけれど)親切な書き方はされていないし、情報にも抜けがあるように見える。実際に試して、動く手順をメモしていく。利用している環境はちょっとバージョンが古い等あるんだけれど、流れを確認するだけなので気にしない。
準備
先ずは下準備。手軽な sqlite 環境で環境を整える。rvm +pow利用が前提。システムの gem を汚さないように gemset も分ける。また今回は gem にすることは考えず、vendor/plugins 以下にプラグインを実装していくやり方。
$ rails new rails3-plugin $ cd ~/.pow $ ln -s ~/rails3--plugin . $ cd $ rvm gemset create rails3-plugin 'rails3-plugin' gemset created (/Users/hogehoge/.rvm/gems/ruby-1.9.2-p290@rails3-plugin). $ echo 'rvm 1.9.2-p290@rails3-plugin' > rails3-plugin/.rvmrc $ cd rails3-plugin ============================================================================== = NOTICE = ============================================================================== = RVM has encountered a new or modified .rvmrc file in the current directory = = This is a shell script and therefore may contain any shell commands. = = = = Examine the contents of this file carefully to be sure the contents are = = safe before trusting it! ( Choose v[iew] below to view the contents ) = ============================================================================== Do you wish to trust this .rvmrc file? (/Users/hogehoge/repos/rails3/rails3-plugin/.rvmrc) y[es], n[o], v[iew], c[ancel]> y $ gem install bundler --no-ri --no-rdoc $ bundle install Fetching source index for http://rubygems.org/ (以下略) $ rake db:migrate $ rake test
yaffle プラグインの作成。
$ rails generate plugin yaffle create vendor/plugins/yaffle create vendor/plugins/yaffle/MIT-LICENSE create vendor/plugins/yaffle/README create vendor/plugins/yaffle/Rakefile create vendor/plugins/yaffle/init.rb create vendor/plugins/yaffle/install.rb create vendor/plugins/yaffle/uninstall.rb create vendor/plugins/yaffle/lib create vendor/plugins/yaffle/lib/yaffle.rb invoke test_unit inside vendor/plugins/yaffle create test create test/yaffle_test.rb create test/test_helper.rb $ rake test:plugins $ cd vendor/plugins/yaffle/ $ rake test Loaded suite /Users/hogehoge/.rvm/gems/ruby-1.9.2-p290@rails3-plugin/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started . Finished in 0.613646 seconds. 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips Test run options: --seed 62222
準備は続く。
プラグインディレクトリ直下にある init.rb をいじる。plugin として動作する際、最初にこのファイルが読み込まれるようだ。plugin を生成すると、プラグインと同名のファイルが lib/ 直下に作成されているのでこれを require するようにしておく。この例で言うと lib/yaffle.rb で、プラグインとしての初期化処理などはこの yaffle.rb で行うのが慣例と言うことかな。これはプラグインの構成によって違うんだろうな。
取り敢えず、require するようにだけしておく。
cd vendor/plugins/yaffle vi init.rb
require "yaffle"
準備というより決めの問題なんだけれども、テストをどのようにするか決めておく必要がある。少なく十テストの実行方法が2パターンあるようだ。rails の test:plugins を利用する方法と、プラグインのディレクトリ内で rake test する方法。最小構成にしたいと考えると、そもそもダミーの rails 環境なんか要らなくて、rails generate plugin で作成したディレクトリの中で rake test すれば良いと思うのだけれど、RAILS_ROOT 上で rake test:plugins した場合とプラグインのディレクトリ内で rake test した場合の挙動が微妙に違う(ーー;
今回は慣れているやり方、つまり RAILS_ROOT 上で rake test:plugins を実行する方でやってみる。因みに特定のプラグインのテストのみを行う場合には rake test:plugins PLUGIN=hogehoge とすれば hogehoge プラグインのみテストを実行できるようだ。今回の場合は rake test:plugins PLUGIN=yaffle と言うことになる。
これで大体準備が完了。
プラグイン機構を通じての String クラスの拡張
3 Extending Core Classess から、これを利用して元のクラスを拡張していくなどの作業をして行く。先ずは String クラスに to_squawk メソッドを追加する。最初にテストを書く。
vi test/core_ext_test.rb
require 'test_helper' class CoreExtTest < Test::Unit::TestCase def test_to_squawk_prepends_the_word_squawk assert_equal "squawk! Hello World", "Hello World".to_squawk end end
これでテストを実行するが当然失敗する。(因みに自分は vim 使うので、vim のコマンドモードから :! (cd ../../../; rake test:plugins PLUGIN=yaffle) してプラグインを実行している)
Loaded suite /Users/hogehoge/.rvm/gems/ruby-1.9.2-p290@rails3-plugin/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started E. Finished in 0.695106 seconds. 1) Error: test_to_squawk_prepends_the_word_squawk(CoreExtTest): NoMethodError: undefined method `to_squawk' for "Hello World":String /Users/hogehoge/repos/rails3/rails3-plugin/vendor/plugins/yaffle/test/core_ext_test.rb:5:in `test_to_squawk_prepends_the_word_squawk' 2 tests, 1 assertions, 0 failures, 1 errors, 0 skips Test run options: --seed 54426 rake aborted! Command failed with status (1): [/Users/hogehoge/.rvm/rubies/ruby-1.9.2-p290/bin...] Tasks: TOP => test:plugins (See full trace by running task with --trace)
ガイドによると、これで開発の準備が出来たとのこと。未実装のコードに対するテストを最初に書くというのを実践しているわけですね。
さて、最初に lib/yaffle.rb で lib//core_ext を require しろとのこと。ってコード見たら違うな…。lib/yaffle/core_ext をrequire していますね。
vi lib/yaffle.rb
require 'yaffle/core_ext' module Yaffle end
最後に lib/yaffle/core_ext.rb で to_squawk メソッドを実装する。というか、yaffle ディレクトリ作るから module Yaffle していたのね。ガイドにはmkdir しろっていう指定は無い。実際この時点でこの module が必要かは怪しい所なんだけどw、後々使うようなので大人しくしたがっておく。
mkdir lib/yaffle vi lib/yaffle/core_ext.rb
String.class_eval do def to_squawk "squawk! #{self}".strip end end
これでテストを実行して成功
Loaded suite /Users/hogehoge/.rvm/gems/ruby-1.9.2-p290@rails3-plugin/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started .. Finished in 0.757923 seconds. 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips Test run options: --seed 11068
実際の挙動を見るには RAILS_ROOT で console して to_squawk を実行してみれば良い
(cd ../../../; rails console) Loading development environment (Rails 3.0.10) ruby-1.9.2-p290 :001 > "Hello World".to_squawk => "squawk! Hello World"
今回は取り敢えずここまで。