はじめに
プロジェクトで用語集を定義するのはBest practiceの一つです。10数年前になりますが、その頃はExcelで用語集を作っているプロジェクトが多かったように思います。しかし、Excelはいろいろきついので、当初はWikiで用語集を作成していました。
しかし、用語が増えるにつれて、Wikiでは長くなり過ぎた表のメンテナンスが苦痛になってきました。その頃、Redmineに用語集プラグイン(Redmine Glossary Plugin)があるのを知り、プロジェクトのRedmineに追加してみました(Redmine 1.0前後)。
https://www.r-labs.org/projects/rp-glossary/wiki/Glossary
なかなか素晴らしいプラグインですが、Redmineのバージョンアップに追従されなくなっていました(2.xあたり)。その頃、Glossary PluginをフォークしてRedmine 2.xで動かしているリポジトリを見つけ、しばらくそちらを利用していました。
https://github.com/chiastolite/redmine_glossary
Redmine 3.0が出たあと、そのリポジトリのものは3.0には対応する気配はありませんでした。そこで、ものは試しとそのリポジトリをフォークしてやみくもにいじって3.0で一見動くようにしてみました。
用語集プラグイン(glossary)をRedmine 3.0で動くようにしてみる - torutkの日記
Githubに置いているので、ちらほら利用されているようです。たまに(年1件程度)issueが書き込まれるのですが、Glossary Pluginの内部を理解していないので、対応することが難しく、結果的に放置となっています。
もう一度Redmineプラグインの作り方をマスターしよう
そこで、再度腰を据えて、このGlossary Pluginの内部を理解し、ひいてはRedmineプラグイン製作ができるようになることを目指すことにしました。
まずはモデルからかな?
Redmineプラグインは、Ruby on Railsのアプリケーションと同様のMVC構造となっています。
そこで、まずは依存関係の一番下にあるM:Modelから理解を始めようとしました。
Glossary Pluginは、3つのモデルクラスが存在しています。
Term、TermCategory、GlossaryStyle の3つのクラスです。
まずはソースコードを読むところから始めよう、と紐解いてみます。
redmine_glossary/term.rb at master · torutk/redmine_glossary · GitHub
term.rbを読んで
class Term < ActiveRecord::Base unloadable
モデルクラス名はTermで、RailsのActiveRecord::Baseクラスを継承しています。
次に、unloadableが登場します。これは、Redmineでモデルの雛形コードを生成すると書かれているものですが、Rails 4(Redmine 3.x)では不要との情報をいただきました。
続いて
belongs_to :category, :class_name => 'TermCategory', :foreign_key => 'category_id' belongs_to :project belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
別テーブルと関連する記述です。同じGlossaryプラグインのモデルTermCategory、Redmine標準のモデルProject、Userへの関連を記述しています。belongs_toは別テーブルと関連付ける方法の1つです。term.category のように属性としてアクセスできるようになります。
通常は、Projectへの関連のようにシンプルに書けます。が、クラス名とは異なる属性名を使用する場合は、class_nameハッシュでクラス名を指定します。foreign_keyの定義は、上の例では省略可能です。
validates_presence_of :name, :project validates_length_of :name, :maximum => 255
これはフィールド(属性)の妥当性検査用コードで、nameフィールド(データベースのtermsテーブルのnameカラムに紐づく)は存在することと長さが最大255であることが条件となっています。
acts_as_attachable
だんだん読むのが苦しくなってきました。これは、Redmineでこのモデルにファイルの添付を可能にする記述です。acts_as_* は、Redmineの内部プラグインとして用意されているものの1つです。クラスレベルメソッド(Redmine::Acts::Attachable::ClassMethods)だそうです。
これだけで添付ファイル機能が利用できる???
acts_as_searchable :columns => ["#{table_name}.name", "#{table_name}.description"], :project_key => [:project]
これは、Redmineでモデルを検索可能にするもののようです。ここからコードの解釈が困難になってきます。:columnsには検索するカラム(カラムの配列)を指定、:project_keyにはProjectの外部キーを指定します。
acts_as_event :title => Proc.new {|o| "#{l(:glossary_title)} ##{o.id}: #{o.name}" }, :description => Proc.new {|o| "#{o.description}"}, :datetime => :created_on, :type => 'terms', :url => Proc.new {|o| {:controller => 'glossary', :action => 'show', :id => o.project, :term_id => o.id} }
検索可能なモデルには、acts_as_eventを定義します。細部定義とどのような使い方をするのかは現時点では分かっていないので、今後調べることとします。
attr_accessible :project_id, :category_id, :author, :name, :name_en, :datatype, :codename, :description, :rubi, :abbr_whole
attr_accessibleを検索すると、Rails 4では非推奨という記述を見かけますが、Redmineではこれを指定しないと変更(データベースの変更)ができないようです。
def author author_id ? User.find_by_id(author_id) : nil end def updater updater_id ? User.find_by_id(updater_id) : nil end def project Project.find_by_id(project_id) end
外部キーで関連付けしたモデルのインスタンスを取り出すメソッドが続きます。
Railsは、モデルにbelongs_toで別モデルと関連づけると、フィールドと同様にterm.authorでインスタンスが取得できるとあるので、これらのメソッドが必要なのかはよくわかりません。
def datetime (self[:created_on] != self[:updated_on]) ? self[:updated_on] : self[:created_on] end
作成日時(created_on)と更新日時(updated_on)の2つの日時を持つので、datetimeメソッドでは新しい方の日時を返却するようにしているようです。
def value(prmname) case prmname when 'project' (project) ? project.name : "" when 'category' (category) ? category : "" when 'datetime' datetime else self[prmname] end end
属性名を文字列で指定するとその値を返すメソッドのようです。
def param_to_s(prmname) if (prmname == 'created_on' or prmname == 'updated_on') format_time(self[prmname]) else value(prmname).to_s end end
指定した属性名の値を文字列化するメソッドです。
def <=>(term) id <=> term.id end
謎のメソッドです。<=>がメソッド名?
まだまだメソッド定義が続きますが、力尽きたのでこの辺で・・・
書籍
acts_as_attachable、acts_as_searchable, acts_as_eventについては、洋書ですが次の書籍に詳しく書かれていました。

Redmine Plugin Extension and Development (English Edition)
- 作者: Alex Bevilacqua
- 出版社/メーカー: Packt Publishing
- 発売日: 2014/03/19
- メディア: Kindle版
- この商品を含むブログ (3件) を見る
4章 Attaching Files to Models に、acts_as_attachableの解説、5章 Making Models Searchable に、acts_as_searchableとacts_as_eventの解説があります。