Ruby Freaks Lounge

第36回 Redmineプラグイン開発(2)

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

マイグレーション

次にマイグレーションを作成します。今回必要になるのはデプロイの履歴を表現するモデルです。名前はDeployHistoryとしましょう。

$ ruby script/generate redmine_plugin_model ContinuousDeployment DeployHistory
$ mv db/migrate/20100314093908_create_deploy_histories.rb db/migrate/001_create_deploy_histories.rb

DeployHistoryモデルは関連モデルに以下の3つを持たせます。

  1. デプロイ時のプロジェクト
  2. デプロイを実施したユーザ(ボタンを押した人)
  3. デプロイ時のチェンジセット

他にもデプロイ開始時刻や終了時刻,実行結果などの属性を持たせます。

001_create_deploy_histories.rb

class CreateDeployHistories < ActiveRecord::Migration
  def self.up
    create_table :deploy_histories do |t|
      t.column :project_id, :integer    # デプロイ時のプロジェクト
      t.column :deployer_id, :integer   # デプロイしたユーザ
      t.column :changeset_id, :integer  # デプロイ時のチェンジセット(リビジョン)
      t.column :started_on, :datetime   # 開始時間
      t.column :deployed_on, :datetime  # 終了時間
      t.column :return_code, :integer   # デプロイの実行結果。コマンドの終了ステータスを保存する。
      t.column :log, :text              # デプロイのログ
    end
  end

  def self.down
    drop_table :deploy_histories
  end
end

一通り作成したらmigrateを実行します。

$ RAILS_ENV=production rake db:migrate_plugins

モデルの実装

続いてモデルです。関連と終了ステータスの名前だけを書いたシンプルなコードです。

deploy_history.rb

class DeployHistory < ActiveRecord::Base
  belongs_to :project
  belongs_to :deployer, :class_name => 'User', :foreign_key => 'deployer_id'
  belongs_to :changeset

  def result_name
    self.return_code == 0 ? "成功" : "失敗"
  end
end

デプロイ履歴画面の実装

さて,まずはデプロイの履歴画面を実装していきましょう。始めにコントローラとビューのファイルを作成します。コントローラの名前はdeployments,履歴画面はindexアクションとしました。

$ ruby script/generate redmine_plugin_controller ContinuousDeployment deployments index

コントローラから実装していきます。

class DeploymentsController < ApplicationController

  before_filter :find_project # ①

  def index
    @histories = DeployHistory.find(:all)
  end

  private

  def find_project
    @project = Project.find(params[:project_id])
  end

プロジェクト配下では@projectインスタンス変数が必須になる為,URLで渡されたプロジェクトIDからProjectモデルのインスタンスを取得し,@projectインスタンス変数にセットしています。基本的にすべての画面で必要になるため,before_filterで記述しています⁠。

次にビューの実装です。デプロイボタンがあること以外は前回とほぼ同様のコードになっています。デプロイを実施するアクション名はdeployとしました。

<style type="text/css">
  table.deploy-histories {
    width: 80%;
  }
  tr.deploy-history {
    text-align:center;
  }
</style>

<h2>デプロイ</h2>

<div style='margin-bottom: 10px'>
  <%= button_to "デプロイ!", { :action => "deploy", :project_id => params[:project_id] }, :confirm => "デプロイします。よろしいですか?" %>
</div>

<table class="list deploy-histories">
  <thead><tr>
    <th>完了日時</th>
    <th>開始日時</th>
    <th>結果</th>
    <th>担当者</th>
    <th>リビジョン</th>
    <th>詳細</th>
  </tr></thead>
  <tbody>
<%- @histories.each do |history| -%>
  <tr class="<%= cycle("odd", "even") %> deploy-history">
    <td><%=h history.deployed_on.strftime("%F %H:%M") %></td>
    <td><%=h history.started_on.strftime("%F %H:%M") %></td>
    <td><%=h history.result_name %></td>
    <td><%=h history.deployer.login %></td>
    <td><%=h history.changeset.revision %></td>
    <td><%= link_to "URL", :action => "show", :id => history.id, :project_id => history.project_id %></td>
  </tr>
<%- end -%>
  </tbody>
</table>

著者プロフィール

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

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