Redmine の自作プラグインでデータベース内の値を利用する

Redmineプラグインを使って何ができるだろう..,
と記事を色々見ていたのですが、データベース内の値を使用している記事を見かけなかったのでここにメモる。

※公式のコードをバリバリ見たというより、手を動かして得た理解になるので細かい箇所の理解が違ってたらご了承ください。

#目次
[1.プラグインの作成](#1-プラグインの作成)
[2.プラグインの編集](#2-プラグインの編集)
[3.表示例](#3-表示例)
[4.テーブル名とクラスの対応関係](#4-テーブル名とクラスの対応関係)
[5.おわりに](#5-おわりに)

#1. プラグインの作成

プラグインは適当な名前で作ってしまいます。

```
ruby script/rails generate redmine_plugin test_plugin
```

http://guide.redmine.jp/Plugin_Tutorial/

#2. プラグインの編集

編集するのは`init.rb`と新しく作成するlib配下の`Hooks.rb`のみ

**init.rb**

```
require 'hooks'

 Redmine::Plugin.register :test_plugin do
   name 'Test Plugin redmine'
   author 'Author name'
   description 'This is a plugin for Redmine'
   version '0.0.1'
   url 'http://example.com/path/to/plugin'
   author_url 'http://example.com/about'
 end
```
テンプレに`Hooks.rb`のrequireを追加しただけ

**lib/Hooks.rb**

```
class Hooks < Redmine::Hook::ViewListener
   def controller_issues_edit_after_save(context)
       STDERR.print(User.all.to_a)
   end
 end
```

   >def controller_issues_edit_after_save(context)

これについては、Redmineのhookというものを使ってます。
ここで、「どのタイミングで中の処理を実行させるか」を決めている感じです。
今回はController hooksの`controller_issues_edit_after_save`を使いました。（名前の通りチケット更新後に処理が始まる感じになります）

↓Hook一覧...いっぱいあります。お好きなタイミングをお選びください

https://www.redmine.org/projects/redmine/wiki/Hooks_List



>STDERR.print(User.all.to_a)

ここはそのまま、RedmineのUserクラスの中身を全部表示させてるのですが、これでRedmineのデータベースのusersテーブルの情報を取得できる様子。
この場合、usersテーブルの値が配列で取得できます。

#3. 表示例
上記２つのファイルを変更した状態でRedmineを開き、チケットを更新すると、コンソールにusersテーブルの値が出力されるはず

表示例↓

```
[
#<User
 id: 1,
 login: "admin",
 hashed_password: "hogehoge-pw",
 firstname: "Redmine",
 lastname: "Admin",
 admin: true, 
 status: 1, 
 last_login_on: "hogehoge-time", 
 language: "", 
 auth_source_id: nil,
 created_on: "hogehoge-time",
 updated_on: "hogehoge-time",
 type: "User", 
 identity_url: nil, 
 mail_notification: "all",
 salt: "hogehoge-salt", 
 must_change_passwd: false, 
 passwd_changed_on: "hogehoge-time", 
 wofa_scheme: nil,
 twofa_totp_key: nil, 
 twofa_totp_last_used_at: nil>,

 #<GroupAnonymous
 id: 2,
 login: "",
 hashed_password: "",
 firstname: "", 
 lastname: "Anonymous users", 
 admin: false, 
 status: 1,  
 last_login_on: nil, 
 language: "", 
 auth_source_id: nil, 
 created_on: "hogehoge-time", 
 updated_on: "hogehoge-time", 
 type: "GroupAnonymous", 
 identity_url: nil, 
 mail_notification: "", 
 salt: nil, 
 must_change_passwd: false, 
 passwd_changed_on: nil, 
 twofa_scheme: nil, 
 twofa_totp_key: nil, 
 twofa_totp_last_used_at: nil>, 

・
・
・
]
```



※ユーザーのIDだけが欲しい時は`Hooks.rb`をこんな感じに変更する。
欲しいデータはDBを確認しつつ、変更の必要あり。

```
class Hooks < Redmine::Hook::ViewListener
   def controller_issues_edit_after_save(context)
     for item in User.all.to_a do
       STDERR.print(item.id)
     end
   end
 end
```


一応下記がテーブル一覧

```
MariaDB [redmine]> show tables;
+-------------------------------------+
| Tables_in_redmine                   |
+-------------------------------------+
| ar_internal_metadata                |
| attachments                         |
| auth_sources                        |
| boards                              |
| changes                             |
| changeset_parents                   |
| changesets                          |
| changesets_issues                   |
| comments                            |
| custom_field_enumerations           |
| custom_fields                       |
| custom_fields_projects              |
| custom_fields_roles                 |
| custom_fields_trackers              |
| custom_values                       |
| documents                           |
| email_addresses                     |
| enabled_modules                     |
| enumerations                        |
| groups_users                        |
| import_items                        |
| imports                             |
| issue_categories                    |
| issue_relations                     |
| issue_statuses                      |
| issues                              |
| journal_details                     |
| journals                            |
| member_roles                        |
| members                             |
| messages                            |
| news                                |
| open_id_authentication_associations |
| open_id_authentication_nonces       |
| projects                            |
| projects_trackers                   |
| queries                             |
| queries_roles                       |
| repositories                        |
| roles                               |
| roles_managed_roles                 |
| schema_migrations                   |
| settings                            |
| time_entries                        |
| tokens                              |
| trackers                            |
| user_preferences                    |
| users                               |
| versions                            |
| watchers                            |
| wiki_content_versions               |
| wiki_contents                       |
| wiki_pages                          |
| wiki_redirects                      |
| wikis                               |
| workflows                           |
+-------------------------------------+
56 rows in set (0.001 sec)
```

#4. テーブル名とクラスの対応関係

テーブル名とクラスの関係ですが、
**[usersテーブル]であれば[Userクラス]
[membersテーブル]であれば[Memberクラス]で値が取得できる**
というようにテーブル名の最初の小文字を大文字にして複数形のsをとってやると対応するクラス名になりそう。（こんな憶測で判断していいものかｗ）
                             

ちなみにアンダーバーがついてるものに関しては、
**[journal_detailsテーブル]であれば[journalクラス]のdetailsプロパティにアクセスすると中身が確認できる。**      

```
     for item in Journal.all.to_a do
       STDERR.print(item.details)
     end               
```

さらに面白かったのがこのテーブル名ですが、どんな対応になるでしょう。
>groups_users

これは
**[Userクラス]のgroupsプロパティでも、
[Groupクラス]のusersプロパティでも同様にデータ取得できました。**



とまあこんな感じでRedmineのプラグインでデータベースの値を利用できるようになりました。

#5. おわりに
データベースの値が利用できるとなると色んな箇所にトリガーをつけて処理ができるので、幅広いプラグインが作れそうですね！