Rails Engine でプラグインを作ってみる。

## はじめに

Rails でCMSパッケージを作成していると顧客の要望によって色々な機能がどんどん追加されていく…

あまり使用しない機能を標準機能として追加していくのは肥大化になりそうだったので、プラグインで拡張機能を管理したいと考えた。

候補として通常のgemで一から作る方法とか、Rails pluginなどを考えたが「[使いやすくなった Rails 3.1 の Engine](http://d.hatena.ne.jp/passingloop/20110801/p1)」の「Rails エンジンの良いところ」を参考にし、Rails Engineが便利そうということが分かった。

とりあえず勉強がてら Rails Guide を参考に動かしてみる。

## 今回作成するサンプル

Rails Guide を参考にblog（記事投稿とコメント）機能を作ってみる。

### プラグイン作成

まずは、プラグイン用のプロジェクトを作成して、記事投稿機能とコメント用のmodelを作成

```zsh
$ bin/rails plugin new blorgh --mountable
$ cd blorgh
$ bin/rails generate scaffold article title:string text:text
$ bin/rails generate model Comment article_id:integer text:text
$ rake db:migrate
```

`app/views/blorgh/articles/show.html.erb` のeditの前に下記を追加する。

```erb:app/views/blorgh/articles/show.html.erb
<h3>Comments</h3>
<%= render @article.comments %>
```

`app/models/blorgh/article.rb`を下記のように修正する。

```rb:app/models/blorgh/article.rb
module Blorgh
  class Article < ActiveRecord::Base
    has_many :comments
  end
end
```

`app/views/blorgh/articles/show.html.erb`の`render @article.comments`の後に下記を追加する。

```erb:app/views/blorgh/articles/show.html.erb
<%= render "blorgh/comments/form" %>
```

app/views/blorgh/commentsにディレクトリを作成する。
その中に_form.html.erbというファイルを作成し、下記を記述する。

```erb:app/views/blorgh/comments/_form.html.erb
<h3>New comment</h3>
<%= form_for [@article, @article.comments.build] do |f| %>
  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>
  <%= f.submit %>
<% end %>
```

conf/routes.rbに下記を追加。

```rb:conf/routes.rb
resources :articles do
  resources :comments
end
```

controllerを追加

```zsh
$ bin/rails g controller comments
```

作成したコントローラー（`app/controllers/blorgh/comments_controller.rb`）に下記を追加する。

```rb:app/controllers/blorgh/comments_controller.rb
def create
  @article = Article.find(params[:article_id])
  @comment = @article.comments.create(comment_params)
  flash[:notice] = "Comment has been created!"
  redirect_to articles_path
end
 
private

def comment_params
  params.require(:comment).permit(:text)
end
```

`app/views/blorgh/comments/` に`_comment.html.erb`ファイルを作成し、以下の記述を追加する。

```erb:app/views/blorgh/comments/_comment.html.erb
<p><%= comment_counter + 1 %>. <%= comment.text %></p>
```

#### 動かしてみる

```zsh
$ cd test/dummy
$ rails s
```

http://localhost:300/articles にアクセスしてみる。
記事を作成後、showからコメントが登録できることを確認する。

注）通常の `rails server` や `rails console` などは `test/dummy` ディレクトリに移動してから実行すること。

## アプリケーションへ作成したプラグインをインストールする。

### プロジェクトの作成

```zsh
$ rails new main_blog_app
$ cd main_blog_app
```

### Gemfileに先ほど作成したプラグインを追加する。

```zsh
$ vi Gemfile

gem 'blorgh', '0.0.1', path: "[plugin_path]/blorgh"

```
注）作成したプラグインのバージョンを記述しないと下記のようなエラーが発生する場合もある。

```
Could not find gem 'blorgh' in source at `../blorgh`.
Source does not contain any versions of 'blorgh'
```

### ルーティングにPluginを追加

```rb:config/routes.rb
mount Blorgh::Engine, at: "/blog"
```

### migrationファイルを生成

```
$ rake railties:install:migrations
$ rake db:migrate
```

注）作成したプラグインのみmigrationしたい場合は下記のコマンドを使用する。

```
$ rake blorgh:install:migrations
$ rake db:migrate SCOPE=blorgh
```


### 動かしてみる

```zsh
$ rails s
```

http://localhost:3000/blog へアクセスできれば完了。


## まとめ

Rails Guide をじっくり読みながら、2-3時間程度で作成できた。
実際にプラグインを作成し、運用をしてみて問題がないかをこれから検証してみたい。

### 参考サイト

Rails Guide
http://railsguides.jp/engines.html
http://dev.classmethod.jp/server-side/ruby-on-rails/rails-engine-vol1_make_subproject/