はじめに
以前、RedmineのWikiでSQLを直接叩いて結果を取得し、出力するマクロを作りました。
上記方法では、生SQLを使用していたためデータベースによって結果が変わってしまうことに気が付きました。近々また調べようと思うと書いたけれど、そんな日は必要に迫られるまで来るはずもなく、今回Redmine 5.1にアップデートするためRedmineのWikiでデータベースの値を取得し表にするマクロを作り直しました。
自作マクロの作成
Redmineは Ruby on Rails を採用しているので、Active Recordを使ってデータベースから情報を取るようにする。以下のように所属するwikiのプロジェクトのバージョンごとにトラッカーと残チケット数を表示するマクロを作る。(バージョンをクリックするとバージョンの説明画面、残チケットの数をクリックすると該当するチケットがフィルタされた画面に飛ぶようリンクを作る。)
バージョン | トラッカー | 期日 | 残チケット |
---|---|---|---|
αリリース | バグ | 2023-11-10 | 1 |
αリリース | 機能 | 2023-11-10 | 2 |
βリリース | 機能 | 2023-11-24 | 1 |
結局、色々試してみたところ以下のコードで意図した表を生成できるようになった。
init.rb
Redmine::WikiFormatting::Macros.register do
desc "Get current project version and status"
macro :get_version_status2 do |obj, args|
str = "<table>"
str << "<thead><tr><th>バージョン</th><th>トラッカー</th><th>期日</th><th>残チケット</th></tr></thead>"
str << "<tbody>"
versions = @project.shared_versions.to_a
versions.each do |version|
results = Issue.joins(:status).joins(:tracker).where(:project_id => @project.id, :fixed_version_id => version.id, status: { is_closed: false }).group("trackers.name").count
results.each {|key, value|
tid = Tracker.find_by_name(key).id
str << "<tr><td>" << link_to(version.name,{:controller => 'versions', :action => 'show', :id => version.id}, :class => 'version') << "</td><td>" << key << "</td><td>" << version.effective_date.to_s << "</td><td>" << link_to(value.to_s, project_issues_path(@project, :fixed_version_id => version.id, :set_filter => '1', :status_id => 'o', :tracker_id => tid.to_s)) << "</td></tr>"
}
end
str << "</tbody></table>"
return str.html_safe
end
end
子プロジェクトに関しても一覧化したい場合
init.rb
Redmine::WikiFormatting::Macros.register do
desc "Get current project version and status"
macro :get_version_status3 do |obj, args|
str = "<table>"
str << "<thead><tr><th>プロジェクト</th><th>バージョン</th><th>トラッカー</th><th>期日</th><th>残チケット</th></tr></thead>"
str << "<tbody>"
1.upto(Project.count) do |pid|
pj = Project.find(pid)
if pj.parent_id == @project.id || pj.id == @project.id then
versions = pj.shared_versions.to_a
versions.each do |version|
results = Issue.joins(:status).joins(:tracker).where(:project_id => pid, :fixed_version_id => version.id, status: { is_closed: false }).group("trackers.name").count
results.each {|key, value|
tid = Tracker.find_by_name(key).id
str << "<tr><td>" << pj.name.to_s << "</td><td>" << link_to(version.name,{:controller => 'versions', :action => 'show', :id => version.id}, :class => 'version') << "</td><td>" << key << "</td><td>" << version.effective_date.to_s << "</td><td>" << link_to(value.to_s, project_issues_path(pj, :fixed_version_id => version.id, :set_filter => '1', :status_id => 'o', :tracker_id => tid.to_s)) << "</td></tr>"
}
end
end
end
str << "</tbody></table>"
return str.html_safe
end
end
きっともっと良い方法があると思うのですが、忘れてしまうので恥を忍んで残しておこうと思います。主にRedmine内のコードを参考にして作成。
動作確認環境
- Redmine 5.1.0.stable.22412
- Ruby version 3.1.4-p223 (2023-03-30) [x86_64-linux]
- Rails version 6.1.7.6
- Database adapter PostgreSQL
参考文献
以下のページを参考にさせて頂きました。ありがとうございました。