2017年10月25日水曜日

Redmineの期日を昇順ソートしたときにnullのチケットを最後に並ぶようにした話


やりたいことたまりすぎ! しかもいくつかは期限付き!みたいな状態です。Riinです。

そこで先日、VPSにRedmine(v3.4 ruby v2.4)を導入してチケットを切って管理することにしました。 (趣味でやることかよって突っ込まれそうですが)

チケットの切り方の方針として、以下を大事にして切っていきます。 
・期日が設定されているものについては優先して片付けるもの 
・期日が設定されていないものについては「いつかやる」もの
そして優先順位を期日ソート(昇順)にしようとしたんです。
 ところが……、期日設定がされていないチケットが先頭で、そのあとで期日の近いものから順番に並んでしまいました!!


理由は明白で、DBにMySQL(v5.7)を選択したために、nullを含むカラムを order by asc でソートするとnullが先頭になります。 つまり、DB側の実装によります。 このあたり、他のDBの仕様を私はよく把握していないためなんともいえませんがDBの実装によってこの並び順は変わってくるんじゃないかと思います。


これをMySQLで解決するためには、 SELECT * FROM table ORDER BY something_datetime IS NULL , something_datetime asc; となるようにしなければいけません。

ところでRedmineはRuby on Railsアプリ。
 クエリはActiveRecordで生成していて、プラグイン機構でこの箇所をオーバライドするか、上記のクエリになるようにモンキーパッチ的な改修を加えなければなりません。
しかしながら私はRubyの文法はインデントスコープなコードですよーってことぐらいしか知らないド素人。
ちょっとコードを追っかけてみて、名前からこの辺かな???っていうのは予想はついたものの、実際にどうしていいかわかりませんでした。 

困って starter-geek-jam のSlackに助けを求めたりしたのですが、回答を待っている間に彼くん(私と同じくエンジニアです)登場。
「主義に反しているんだけど……」とぶつくさ言いながら1時間くらいでモンキーパッチで修正する場合の修正箇所を突き止めてくれました。


app/modells/issues_query.rb 
- QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"), 
+ QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date IS NULL,#{Issue.table_name}.due_date"),



わーい、ありがとう!


0 件のコメント:

コメントを投稿