あらすじ
Redmine 2.0台におけるインストール方法〜起動方法とプラグインの作り方のメモ。
環境
- Windows 7 32bit
- Ruby 1.9.3
- Bundler 1.3.5 導入済
- DevKit 導入済
- Redmine 2.3.1
- MySql 5.6.12.1
参考サイト
- Redmineのインストール — Redmine Guide 日本語訳
- Hooks - Redmine
- Hooks List - Redmine
- プラグイン ホック - r-labs
- ビュー(view) - Railsドキュメント
Redmineインストール手順
まずは準備。
MySQL
実はMySQLさわるのはじめてかもしれない。
- MySQL :: Download MySQL Installer からインストーラをDL。Oracleのアカウントが必要
- 基本的にPathなどの設定はそのまま。
- Choosing a Setup Type:
Developer Default
を選択 - MySQL Server Configuration:
- Server Configuration Type は
Development Machine
- ポートは
3306
root
のパスワードを入力- Windows Service Details の
Start the MySQL Server at System Startup
のチェックだけKILL
そんなに使わないしPCがしょぼいので常時起動させておくこともない
- Choosing a Setup Type:
全部終わると MySQL Workbench が立ち上がる。
- Open Connection to Start Queryin に
Local instance MySQL56
を選択 - root のパスワードを入力し、ログインできる事を確認
- コンソールから
redmine
ユーザを作成し、 テーブルの権限を設定する (これをよく忘れてaccess denied
になる)
create database redmine character set utf8;
create user 'redmine'@'localhost' identified by 'my_password';
grant all privileges on redmine.* to 'redmine'@'localhost';
で、とりあえずオッケー。
Redmine
- Redmine 2.3.1 をDLし、適当なところへ解凍。
config/database.yml.example
をconfig/database.yml
にリネームし、内容編集。MySQLとつなげるように
production:
adapter: mysql2
database: redmine
host: localhost
username: redmine
password: my_password
encoding: utf8
development:
adapter: mysql2
database: redmine_development
host: localhost
username: redmine
password: my_password
encoding: utf8
Ruby 1.9 からMySQLにつなぐには adapter は mysql2 である必要がある模様。
- そして
bundle install --path vendor/bundle --without rmagick
- rmagickは頑張って入れてもいいけど今回はwithoutする
MySQL アダプターがなんか言ってる…my-sql-connector-c?
(略)
Installing mysql2 (0.3.11)
(略)
Using yard (0.8.6.2)
Your bundle is complete!
Gems in the group rmagick were not installed.
It was installed into ./vendor/bundle
Post-install message from mysql2:
======================================================================================================
You've installed the binary version of mysql2.
It was built using MySQL Connector/C version 6.0.2.
It's recommended to use the exact same version to avoid potential issues.
At the time of building this gem, the necessary DLL files where available
in the following download:
http://dev.mysql.com/get/Downloads/Connector-C/mysql-connector-c-noinstall-6.0.2-win32.zip/from/pick
And put lib\libmysql.dll file in your Ruby bin directory, for example C:\Ruby\bin
======================================================================================================
とりあえず落としてきて、 lib/libmysql.dll
をRubyのbinディレクトリにいれた。
- セッションストア秘密鍵の作成
- テーブルの作成
- デフォルトのロール、トラッカー、ステータス、ワークフロー、列挙項目のロード
$ rake generate_secret_token
$ set RAILS_ENV=production
$ rake db:migrate
== Setup: migrating ==========================================================
-- create_table("attachments", {:force=>true})
-> 0.1700s
(略)
$ rake redmine:load_default_data
Select language: ar, az, bg, bs, ca, cs, da, de, el, en, en-GB, es, et, eu, fa, fi, fr, gl, he, hr,
hu, id, it, ja, ko, lt, lv, mk, mn, nl, no, pl, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en] ja
====================================
Default configuration data loaded.
- 起動
$ ruby script\rails server
起動したら admin/admin
でログインして情報を見に行ってみる。
Environment:
Redmine version 2.3.1.stable
Ruby version 1.9.3 (i386-mingw32)
Rails version 3.2.13
Environment production
Database adapter Mysql2
Redmine plugins:
no plugin installed
OK。
プラグイン作成の準備
コマンド
コマンドは script/rails
に集約されたっぽい?
今まで script/xxx
とかやっていたコマンドは script/rails xxx
になっている。
$ ruby script\rails -h
bundler is found: bundle exec ruby script\rails -h
Usage: rails COMMAND [ARGS]
The most common rails commands are:
generate Generate new code (short-cut alias: "g")
console Start the Rails console (short-cut alias: "c")
server Start the Rails server (short-cut alias: "s")
dbconsole Start a console for the database specified in config/database.yml
(short-cut alias: "db")
new Create a new Rails application. "rails new my_app" creates a
new application called MyApp in "./my_app"
In addition to those, there are:
application Generate the Rails application code
destroy Undo code generated with "generate" (short-cut alias: "d")
benchmarker See how fast a piece of code runs
profiler Get profile information from a piece of code
plugin Install a plugin
runner Run a piece of code in the application environment (short-cut alias: "r")
All commands can be run with -h (or --help) for more information.
スケルトン作成
ruby script/rails generate redmine_plugin PLUGIN_NAME
で作成。
- プラグイン名はスネークケース
plugins/
下に作成される
$ ruby script\rails generate redmine_plugin download_issues_with_journal
bundler is found: bundle exec ruby script\rails generate redmine_plugin download_issues_with_journal
create plugins/download_issues_with_journal/app
create plugins/download_issues_with_journal/app/controllers
create plugins/download_issues_with_journal/app/helpers
create plugins/download_issues_with_journal/app/models
create plugins/download_issues_with_journal/app/views
create plugins/download_issues_with_journal/db/migrate
create plugins/download_issues_with_journal/lib/tasks
create plugins/download_issues_with_journal/assets/images
create plugins/download_issues_with_journal/assets/javascripts
create plugins/download_issues_with_journal/assets/stylesheets
create plugins/download_issues_with_journal/config/locales
create plugins/download_issues_with_journal/test
create plugins/download_issues_with_journal/test/fixtures
create plugins/download_issues_with_journal/test/unit
create plugins/download_issues_with_journal/test/functional
create plugins/download_issues_with_journal/test/integration
create plugins/download_issues_with_journal/README.rdoc
create plugins/download_issues_with_journal/init.rb
create plugins/download_issues_with_journal/config/routes.rb
create plugins/download_issues_with_journal/config/locales/en.yml
create plugins/download_issues_with_journal/test/test_helper.rb
plugins/
下にいれば、Redmine起動時にロードしてくれる。再起動して情報を見に行くと…。
Environment:
Redmine version 2.3.1.stable
Ruby version 1.9.3 (i386-mingw32)
Rails version 3.2.13
Environment production
Database adapter Mysql2
Redmine plugins:
download_issues_with_journal 0.0.1 # => 増えてる!
init.rb
書き方が、Rubyのそれとちょっと違う。Rails流?なので、はじめは慣れが必要かも。
- 文字列ではなく、なるべくシンボルを使う
- ブロックは括弧 {} ではなく、 do, end を使う
- メソッドの括弧 () は省略する
今は特にすることもないので、authorやurlを適当に編集したら次へ。
viewのフック
「特定の画面に何か文字とか機能を追加する」場合、viewをフックすることで実現できる。(他にも手段はあるみたいだが、とりあえず)
どこにフックできるかは、 app/views下のerbファイル
を確認し、 call_hook(xxx)
と書かれているところがそうらしい。詳しくは参考サイト参照
今回は、チケット一覧のページにフックしたいので、その辺を探してみる…。
すると、 app/views/issues/index.html.erb
の中にこんな記述が。ページの一番下の部分にフックできそう。
<%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
第一引数 :view_issues_index_bottom
はフックする時に作成するメソッド名になる、第2引数はパラメータ。これは覚えておく。
フックファイル
PLUGIN/lib/PLUGIN_NAME/hooks.rb
を作り、以下のように記載。
class Hooks < Redmine::Hook::ViewListener
def view_issues_index_bottom(context)
puts "view_issues_index_bottom"
return "<p>Hello</p>"
end
end
call_hookの第一引数になっていたとおり、 view_issues_index_bottom
メソッドを作る。
次に上記のフックを読み込むために init.rb
に require を追加する。
require 'download_issues_with_journal/hooks'
これで Redmine を再起動すると、チケット一覧ページに Hello と表示されているはず。
Viewファイル
また、View担当部分はきちんとViewにわけることもできる。
フック部分を以下のように変更。
class Hooks < Redmine::Hook::ViewListener
def view_issues_index_bottom(context)
context[:controller].send(:render_to_string, {
:partial => "hooks/download_issues_with_journal/view_issues_index_bottom",
:locals => context })
end
end
:partial
は app/views/
以下のパスを指定。
上記のように指定すると app/views/hooks/download_issues_with_journal/_view_issues_index_bottom.html.erb
(部分描画用のファイルは先頭に _
を付けるのがルール)が呼ばれる。中身はこんな感じ。
<div class="contextual">
<%= @project %>
<%= link_to("link ror", "http://rubyonrails.org") %>
</div>
チケット一覧を開いているプロジェクト名とRuby on Railsへのリンクが表示される。
これでViewをフックしつつ、Viewの定義自体はerbファイルに追い出すことができた。
Controllerと連携
ここまでViewをいじっていると、ファイル構造はこんな感じになった。
download_issues_with_journal
├─app
│ └─views
│ └─hooks
│ └─download_issues_with_journal
│ └─_view_issues_index_bottom.html.erb (3)
├─assets
├─config
├─db
├─lib
│ └─download_issues_with_journal
│ └─hooks.rb (1)
├─init.rb (2)
└─test
(1)でチケット一覧画面をフックし、(2)でそれをrequire、(3)に追加したい画面ソースを書いた。
次にController(ユーザのアクションに対応したメソッド)を作り、Viewと連携を取る。
いじるファイルは以下。
- Controllerファイル(新規作成)
- Viewファイル(Controllerを呼ぶように編集)
- Routeファイル(編集)
Controller
app/controller/export_controller.rb
を作成。
- export_controller なので、、
export
がこの先:controller
に指定する名前になる - ApplicationController クラスを継承
- unloadable を書かないと Development モードで動かない。今はおまじないでいい
- 処理を書いていく。メソッド名が
:action
となる
class ExportController < ApplicationController
unloadable
def export_with_journal
puts "export_with_journal"
send_data("aa", :type => "text/csv", :filename => "test.csv")
end
end
View
Controller に定義した :controller と :action 名に従って、リンク先を変更する。
<div class="contextual">
<%= link_to("dl #{@project} issues", {:controller => "export", :action => "export_with_journal"}) %>
</div>
Route
Controller と View を結びつける。
match 'projects/export/:action', :controller => 'export'
これで、ViewのリンクをたたくとControllerが呼ばれる。