今回のブログ担当は石川です。今回はRedmineのプラグインの話をしようと思います。
少し前にRedmineの用語やメッセージを管理画面で自由に変更できるプラグイン「メッセージカスタマイズプラグイン」を公開しました。 https://github.com/ishikawa999/redmine_message_customize
「"トラッカー"という言葉が分かりにくいため"チケット種別"に置き換えたい」と考えたとき、通常はRedmineが動いているサーバーに入ってlocales/ja.ymlファイルを書き換える必要がありますが、メッセージカスタマイズプラグインを使うとRedmineの管理画面から変更できます。
利用方法については紹介している記事( Redmineの用語やメッセージを管理画面で自由に変更できるプラグイン「メッセージカスタマイズプラグイン」 )がすでににあるため省略して、今回は少し珍しい構成でプラグインを作ったので、それを共有しようと思います。
※ これは2019/10/21時点での実装の話なので、今後変わるかもしれません
メッセージカスタマイズプラグインは、実は独自のテーブルを追加したりはしていないため導入時に「bundle exec rake redmine:plugins:migrate」などのコマンドを実行しなくても動くようになっています。プラグイン導入時にマイグレーションを実行し忘れてうまくいかなかったりという話もよく聞きますし、マイグレーション無しで動くプラグインは導入難易度が低いような気がしますね。
ただ、なにも保存する必要のないプラグインかというとそうではなく、上書きするメッセージなどの値をDBに保存しています。
メッセージカスタマイズプラグインは独自のテーブルを追加したりする代わりに、Settingテーブルに値を格納しています。
Settingテーブルのテーブル構造
Column | Type | Modifiers
------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('settings_id_seq'::regclass)
name | character varying(255) | not null default ''::character varying
value | text |
updated_on | timestamp without time zone |
見ての通り、id・name・value・update_onという4つのカラムしか持っていません。valueはtext型ですが、シリアライズして保存するようになっているため配列やHashなどを収めることができるようになっています。(シリアライズについては[UserPreferenceも同じ](/blog/2019/06/redmine-userpreference) )
Settingテーブルは管理画面の設定を保存するのに使われていて、
[1] pry(main)> Setting.find_by(name: 'non_working_week_days') Setting Load (0.6ms) SELECT "settings".* FROM "settings" WHERE "settings"."name" = $1 LIMIT $2 [["name", "non_working_week_days"], ["LIMIT", 1]] => #<Setting:0x000056484ee28b40 id: 25, name: "non_working_week_days", value: "---\n- '6'\n- '7'\n", updated_on: Mon, 21 Oct 2019 04:33:55 UTC +00:00>
のように保存されています。valueには配列['6', '7']
を変換した"---\n- '6'\n- '7'\n"
という文字列が入っていて、Setting.find_by(name: 'non_working_week_days').value
は['6', '7']
を返すようになっています。
Settingテーブルにプラグインの設定を保存する仕組み自体は実は元から提供されており、プラグインのinit.rbでsettingsの設定をするだけで利用できます。
詳細: Redmine プラグイン チュートリアル(プラグインの設定画面の追加)
[Redmineチュートリアルの例]
Redmine::Plugin.register :redmine_polls do [ ... ] settings :default => {'empty' => true}, :partial => 'settings/poll_settings' end
のように設定しておくとpartialとして指定したファイルを元にプラグインの設定画面が作られ、そこで保存した値はSetting.plugin_<プラグイン名>
のようなメソッドで簡単にアクセスできるようになっています。
> Setting.plugin_redmine_polls {'empty' => true}
「プラグインの設定類を保存する仕組み」があると紹介しましたが、メッセージカスタマイズプラグインでは保存前に値に対してバリデーションチェックを行ったり保存前に値を変換したりということがしたかったため、Settingクラスであらかじめ実装されている値をそのまま保存する仕組みだけでは不十分でした。
そこで、Settingクラスを継承したCustomMessageSettingクラスを作り、そこに独自の処理を追加していきました。
(値を保存する場所はSettingテーブルのまま)
class CustomMessageSetting < Setting validate :convertible_to_yaml, :custom_message_languages_are_available, :custom_message_keys_are_available def self.find_or_default super('plugin_redmine_message_customize') end def enabled? self.value[:enabled] != 'false' end def custom_messages(lang=nil, check_enabled=false) # 省略 end def custom_messages_to_yaml # 省略 end # 省略 end
それに合わせてCustomMessageSettingsControllerやViewなども追加しています。
こうすることで、「プラグインの設定類を保存する仕組み」では対応しきれないような複雑な処理にも対応できました。
全体を読み込んでからHashや配列に変換されるため、結構遅いです。頻繁に利用される値を保存しておきたい場合は独自のテーブルを追加したり、既存のテーブルにカラムを追加して使うべきです。
値を取得してからArray#selectなどを使えばできなくもありませんが、頻度が高いならするべきではないと思います。
PostgreSQLなどは割とたくさん入りますが、MySQLは上限が近いので長い文字列を持つHashなどを入れると溢れてしまうかもしれません。使い方によってデータの量が増える可能性のあるプラグインの場合は使わない方がよさそうです。
RedmineのSettingテーブルをプラグインの設定などをいれる場所として利用する手法を紹介しました。
Settingテーブルのvalueカラムなどのシリアライズされるカラムには何でも保存できるため、ついつい軽い気持ちで使いたくなってしまいますが、高い頻度で利用したり、保存したり、検索したりするような値を保存するためには使うべきではありません。その値が本当にSettingテーブルのvalueカラムに保存して良い物かの判断は慎重に行うようにしましょう。
メッセージカスタマイズプラグインの場合は、i18nの読み込みタイミングとプラグイン独自の編集画面でしか値を利用することはないため利用頻度が低く、容量的にもそこまで使うプラグインではないためSettingテーブルのvalueを使うことにしました。
注意が必要ではありますが、導入しやすいプラグインを作る上では実装の選択肢に入れてみても良いんじゃないかなと思います。
![]() |
Redmineの中で定義されているモデル「UserPreference」のようなデータの持ち方は、Redmineをもっと便利にすると思います。 |
![]() |
macOS Catalinaにアップグレードに伴いiTunesが終了。問題なく音楽データは引き継がれるか、検証しました。 |
![]() |
避難訓練から防災訓練に名称を変更し、消火器やビルの消防設備について研修を実施しました。訓練を行うことで万一の際に役立ちます。 |
![]() |
AWSのFargateを利用して、RailsのDB作成とマイグレーションを複数サイトで同時実行してみました。Fargate最高! |
![]() |
中国の深圳大学に語学留学して、中国語を4週間学んできました。授業の様子と滞在中の生活を紹介。 |
![]() |
社員研修に伴うサポート体制変更・休業のお知らせ(5/20〜23) 社員研修に伴い、5月20日〜23日はサポート体制の変更および休業とさせていただきます。 |
![]() |
オープンソースカンファレンス2025 Nagoyaに弊社代表の前田が登壇(ブース出展あり) オープンソースカンファレンス(OSC)2025 Nagoyaに弊社代表の前田が登壇。『Redmineの意外と知らない便利な機能(Redmine 6.0 対応版)』をテーマに発表します。 |
![]() |
エンタープライズプラン向け「優先サポート」を開始 My Redmineでは、エンタープライズプランをご契約のお客様向けにサポート対応を優先的に行う「優先サポート(プライオリティサポート)」を開始いたしました。 |
![]() |
プロジェクト管理ツール「RedMica」バージョン 3.1.0をリリース Redmine互換のオープンソースソフトウェア ファーエンドテクノロジー株式会社は、2024年11月19日(日本時間)、Redmine互換のプロジェクト管理ソフトウェア「RedMica 3.1.0」をリリースしました。 |
![]() |
Redmineの最新情報をメールでお知らせする「Redmine News」配信中 新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け |