Ruby Freaks Lounge

第34回 Redmineプラグイン開発(1)

この記事を読むのに必要な時間:およそ 6 分

モデルの実装

次にモデルを作成します。今回必要になるのはサーバとサーバのステータス変更履歴を表現する二つのモデルです。

通常はそれぞれでテーブルを作成しますが,今回は履歴用のモデルにはRedmineで使用しているcommentsテーブルを使ってみましょう。commentsテーブルはRailsの Polymorphic Associationを使って実装されており,様々なモデルに対するコメントを集約しているテーブルです。現在はニュース機能へのコメントのみを扱っていますが,将来的に機能が追加された際はこのテーブルが使われることでしょう。

redmine_plugin_modelジェネレータでServerモデルを作成します。

$ ruby script/generate redmine_plugin_model ServerStatus Server name:string, status:integer, comment_counts:integer

redmine_plugin_modelの引数は以下の通りです。初めにプラグイン名を指定する以外はRailsと同じですね。

redmine_plugin_model <plugin_name> <model_name> [ <column_name:column_type>, ...]

なお,comment_countsというカラムにはそのサーバのコメント(=履歴)数が格納されます。counter cacheというRailsの機能で実現されており,実装者が意識する必要はありません。

モデルにリレーションや基本的なロジックを記述していきます。

app/models/server.rb

class Server < ActiveRecord::Base

  has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on DESC" 

  module Status
    WORKING = 1
    STOPPED = 2
  end

  def status_name
    case self.status
    when Status::WORKING
      "稼働中" 
    when Status::STOPPED
      "停止" 
    end
  end
end

マイグレーション

次にマイグレーションと初期データを投入します。

モデルを作成した時点でPLUGIN_ROOT/db/migrateディレクトリ以下にマイグレーションファイルが作成されています。ただし,Redmineのプラグインはタイムスタンプ式のマイグレーションに対応しておらず,連番のファイル名に変更する必要があります。

mv ${PLUGIN_ROOT}/db/migrate/20100301102344_create_servers.rb ${PLUGIN_ROOT}/db/migrate/001_create_servers.rb

また,Rails 2.3.4から初期データはdb/seeds.rbに書くことが推奨されていますが,残念ながらvendor/plugin以下にあるseeds.rbは読み込んでくれません。今回はmigrationファイルに直接記述してしまいましょう。

db/migrate/001_create_servers.rb

class CreateServers < ActiveRecord::Migration
  def self.up
    create_table :servers do |t|
      t.column :name, :string
      t.column :status, :integer
      t.column :comments_count, :integer, :default => 0
    end

    (1..8).each{|i| Server.create!(:name => sprintf("server%02d", i), :status => Server::Status::WORKING)}
  end

  def self.down
    drop_table :servers
  end
end

一通りの修正が完了したらマイグレーションを実施します。

$ rake db:migrate_plugins

コントローラ・ビューの実装

さて,それではいよいよコントローラの実装に入ります。

まずはredmine_plugin_controllerジェネレータでファイルを作成します。

$ ruby script/generate redmine_plugin_controller ServerList servers index

PLUGIN_ROOT/app/controllers 以下にservers_controller.rbが, PLUGIN_ROOT/app/views/servers/以下にindex.html.erbファイルができました。

次にコントローラの実装です。Serverモデルからすべてのレコードを名前順に取得します。なお,実装についてですが,Redmineと関連しない箇所に関しては通常のRailsアプリと同じ感覚でコードを記述しても問題ありません。

app/controllers/servers_controller.rb

class ServersController < ApplicationController

  def index
    @servers = Server.find(:all, :order => "name ASC")
  end

end

次にビューです。@servers変数を展開してサーバ名とステータスを書き出しています。

app/views/servers/index.html.erb

<style type="text/css">
table.servers {
width: 60%;
}
</style>
<h2>サーバ一覧</h2>

<table class="list servers"> <!-- ① -->
<thead><tr>
<th>サーバ名</th>
<th>状態</th>
</tr></thead>
<tbody>
<%- @servers.each do |server| -%>
<tr class="<%= cycle("odd", "even") %> server">
<td><%=h server.name %></td>
<td><%=h server.status_name %></td>
</tr>
<% end %>
</tbody>
</table>

①ではテーブルのclass属性にlistを指定しています。このクラスはチケットの一覧画面など,表形式のビューで共通して使われており,指定することでレイアウトやマウスオーバー時のハイライトなどがおこなわれます。Redmine本体のバージョンアップに伴いレイアウトが崩れる可能性がありますが,デザインの手間を省くことができ,UIが統一されますのでメリットの方が大きいと個人的には考えています。

これで準備完了です。アプリケーションサーバを再起動してブラウザをリロードしてみましょう。トップメニューに「サーバ一覧」追加されていて,そのリンクにアクセスすると以下のような画面が表示されるはずです。

図3 サーバ一覧画面

図3 サーバ一覧画面

著者プロフィール

京和崇行(きょうわたかゆき)

株式会社カカクコム所属。食べログをRailsでリニューアルした時のメンバーの一人。 今は主にサーバサイドの開発とチューニングを担当…のはずだが他にも色々やっている。 クライミングとニコニコ動画とtwitterがあれば生きていける。