【ニコニコカレンダー for Redmine 2.X】 初日

Redmineのプラグイン開発ってどうやるんだべー、ということで、まずは
Plugin Tutorial - Redmine
プラグイン開発ガイド - r-labs
に軽く目を通す。

必要なものはRedmine(およびベースになっているRails?)がスケルトンを生成してくれるのね。さすがです。

1. プラグインのスケルトンの生成

1.1. スケルトンの作成

スケルトン生成用コマンド
ruby script/rails generate redmine_plugin ${プラグイン名}


Redmineのルート直下で以下をたたく!

$ export RAILS_ENV="development" 
$ ruby script/rails generate redmine_plugin redmine_nikoniko_calendar2

すると、

create  plugins/redmine_nikoniko_calendar2/app
create  plugins/redmine_nikoniko_calendar2/app/controllers
create  plugins/redmine_nikoniko_calendar2/app/helpers
   (中略)
create  plugins/redmine_nikoniko_calendar2/config/routes.rb
create  plugins/redmine_nikoniko_calendar2/config/locales/en.yml
create  plugins/redmine_nikoniko_calendar2/test/test_helper.rb

べろっと「vendor/plugins/$(プラグイン名)」配下にスケルトンを作成してくれます。

生成されたプラグインの構成については
GuideSkeleton - r-labs
にまとめてくださっているのを参照するのが良し。

1.2. 「README.rdoc」, 「init.rb」を編集する

それっぽく編集。あとでちゃんと書く。

1.3. 再起動、確認

Redmine直下のtmpディレクトリに「restart.txt」を空ファイルで作成し、Redmineにアクセスすることで再起動できるらしい。
知らなかった・・・。いつもApache再起動してたよ。。。

いくつかの参考にしたサイトでは再起動後、「restart.txt削除される」という記述もあったが、手元の環境では削除されなかった。
ただ、再度touchすると再起動かかるので、mtimeでも見てるのかしら。。。今度調べよう。

再起動後、「管理 > プラグイン」と進み、一覧に作成したプラグインが表示されていれば問題なし。

2. モデルの作成

2.1. スケルトンの生成

スケルトン生成コマンド
ruby script/rails generate redmine_plugin_model ${プラグイン名} ${テーブル名}

Redmineのルート直下で以下をたたく!

$ ruby script/rails generate redmine_plugin_model redmine_nikoniko_calendar2 nikoniko_history

すると、3ファイル生成される。

create  plugins/redmine_nikoniko_calendar2/app/models/nikoniko_history.rb
create  plugins/redmine_nikoniko_calendar2/test/unit/nikoniko_history_test.rb
create  plugins/redmine_nikoniko_calendar2/db/migrate/001_create_nikoniko_histories.rb

2.2. Migrationファイルの作成

プラグインが必要とするデータベースのテーブルの作成(削除)は「Migration」という処理によって行われる。
plugins/redmine_nikoniko_calendar2/db/migrate/001_create_nikoniko_history.rb
を以下のように編集した。

class CreateNikonikoHistories < ActiveRecord::Migration
  def up
    create_table :nikoniko_histories do |t|
      t.references("user")
      t.column "date", :date, :null => false
      t.column "niko", :"CHAR(1)", :null => false
      t.column "comment", :string, :limit => 140
    end
    
    # add unique index
    add_index :nikoniko_histories, [:user_id, :date], :unique => true
    
    # add foreign key
    execute "ALTER TABLE nikoniko_histories ADD CONSTRAINT `fk_:nikoniko_histories_on_user_id` FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE"
  end
  
  def down
    drop_table :nikoniko_histories
  end
end

より突っ込んだMigrationファイルの記述方法はマイグレーション(migration) - Railsドキュメントを参考にすると良し。

2.3. テーブルの作成(削除)

・Migrationファイルに基づいたテーブルの作成

$ rake redmine:plugins:migrate NAME=redmine_nikoniko_calendar2

・テーブルの削除

$ rake redmine:plugins:migrate NAME=redmine_nikoniko_calendar2 VERSION=0

3. コントローラの作成

3.1. スケルトンの生成

スケルトン生成コマンド
ruby script/rails generate redmine_plugin_controller ${プラグイン名} ${コントローラ名} ${アクション名}

${コントローラ名}は「スネークケース(snake_case)」で記述しないと後々以下のエラーに苦しむことになります。。。。

ActionController::RoutingError (uninitialized constant NikonikoCalendarController):


Redmineのルート直下で以下をたたく!

$ ruby script/rails generate redmine_plugin_controller redmine_nikoniko_calendar2 nikoniko_calendar index

すると、4ファイル生成される。

create  plugins/redmine_nikoniko_calendar2/app/controllers/NikonikoCalendar_controller.rb
create  plugins/redmine_nikoniko_calendar2/app/helpers/NikonikoCalendar_helper.rb
create  plugins/redmine_nikoniko_calendar2/test/functional/NikonikoCalendar_controller_test.rb
create  plugins/redmine_nikoniko_calendar2/app/views/NikonikoCalendar/index.html.erb

3.2. ルーティングの設定

プラグインのconfig/routes.rbにルーティング情報を設定する。
ファイル中のコメントに

# See: http://guides.rubyonrails.org/routing.html

とあるので、素直にリンク先をふむふむ、と読む。
様々な記述方法があるようだが、自分にしっくり来た以下のような記述を追加した。

match 'nikoniko_calendar', :controller => :NikonikoCalendar, :action => :index, :via => :get

以下も直感的で分かりやすいが、やっぱ上だな。(くどい?のかな、自分)

get 'nikoniko_calendar', :to => 'NikonikoCalendar#index'

4. メニューにプラグインへのリンクを追加

There are five menus that you can extend:

:top_menu - the top left menu
:account_menu - the top right menu with sign in/sign out links
:application_menu - the main menu displayed when the user is not inside a project
:project_menu - the main menu displayed when the user is inside a project
:admin_menu - the menu displayed on the Administration page (can only insert after Settings, before Plugins)

らしいので、とりあえずapplication_menuに追加。
以下のコードをプラグインのinit.rbに追加

menu :application_menu, :nikoniko_calendar, { :controller => 'NikonikoCalendar', :action => 'index' }, :caption => :nikoniko_calendar

ちなみに、captionに日本語を指定すると、

Exception ArgumentError in spawn manager (invalid byte sequence in US-ASCII) (process 4823, thread #):

なエラーに。。。。。。
I18Nファイルをconfig/locales配下に作成し、そのキーを指定することで回避。


ぐふぅ。。。ルーティングで設定したURLにアクセスしてプラグインのコントローラが動作することを確認。
Rubyの文法がわからないことだらけなので調べなければ。。。。