「rails console」を使ってRedmine上のスケジュールを一括変更する方法

# 「rails console」を使ってRedmine上のスケジュールを一括変更する方法

[Redmine Advent Calendar 2023](https://adventar.org/calendars/8974)の20日目の記事として作成しました。


* * *
## 背景

プロジェクトは長期の工程を扱ったり、不確実性な要素をたくさん含んでいるため、外部や内部の要因でプロジェクトの途中でスケジュールの変更やリソースの変更、予算の変更などが頻繁に発生します。そのため、プロジェクト管理ツールは、プロジェクトの変更に合わせて、柔軟にシステム上でも情報を変更できる必要があります。しかし、残念ながら、Redmineでスケジュールを一括変更させる方法がありません。

Redmineでスケジュール管理をする一般的な方法を確認します。Redmineでスケジュール管理をするためには、チケットに開始日、期日を登録すると、自動的にガントチャートを作成できるので、スケジュールの管理をガントチャートで確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/c80535a4-9daf-157d-9a70-d41ab6bc1500.png)


複数のチケットの登録は、チケットのインポート機能を使うことにより可能です。CSVファイルでチケットのタイトル、開始日、期日を作成して、「チケットのインポート」機能でガントチャートで表示するチケット一覧を一括の作業で作成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/10464cfd-6fe2-07d6-9916-5efd199525fb.png)

また、一度作成されたチケットは「チケットの一括編集」機能で、複数のチケットを対象に、優先度、担当者、ステータス、開始日、期日などを修正、変更することができ、プロジェクトの進捗に合わせて、必要な情報を迅速に変更することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/2441cbfc-1e4b-2b47-2448-49dd2a53a23d.png)


「チケットのインポート機能」では、新規のチケットを大量に同時に登録ができ、「チケットの一括編集機能」で登録したチケットを同時に多数のチケットを対象に編集をすることができますが、どちらの場合も「一括して同時に多数のチケット」を「個別に編集、変更」することができません。

先行タスクと後行タスクがある場合、先行タスクが遅れると、後行タスクがその遅れた分を一括で後ろ倒しにスケジュールを変更しなければならない場合があります。上記の「チケットのインポート機能」や「チケットの一括編集機能」では、ある特定の条件に属している各チケットの開始日と期日を指定日数分遅らせるということができません。

例えば、Aチケットの開始日は1/1、Bチケットの開始日は1/15、Cチケットの開始日は1/20の場合、各チケットを3日だけ後ろにずらし、かつ、各チケットの期日も3日分遅らせる処理は「チケットの一括編集機能」では対応できません。「チケットの一括編集機能」はあくまでも複数のチケットの開始日や期日を同じ日として変更してしまうため、元の値を考慮して「プラス3日」遅らせるという処理をすることができません。

この問題を解決するために「rails console」を使ってRedmine上のスケジュールを一括変更する方法を紹介します。


## 前提条件

Redmineがインストールされているサーバーにターミナルでアクセスできる必要があります。
下記の例示はRedmine4.2.8で確認をしました。他のバージョンのRedmineでは正しく動作しない可能性があります

## 対処方法

### 1.  「rails c」を実行

ターミナルを開いて、Redmineがインストールされているパスで「rails c -e production」を実行します。
「rails c」の代わりに「rails console」でも構いません。

```ruby
  rails c -e production
```

<img width="100%" alt=" 「rails c」を実行" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/c654fa3c-33fb-a79c-b0cb-08559a2608ef.png">
＜ 「rails c」を実行＞

### 2. 特定のプロジェクトに属している全てのチケットを指定日数遅延させる方法

「rails console」で下記のコマンドを実行することで、特定のプロジェクトに属している全てのチケットを指定日数遅延させることができます。
プログラムソースを見ていただくとすぐに分かると思いますが、Issueモデルからproject_idが1で、かつ、開始日と期日に値が登録されているチケットを「issues」という変数で取得します。
issues変数の各要素を取り出して、そのチケットの開始日と期日に指定日数、下記の場合は、3日をプラスして、元々のチケットの開始日と期日としてその値を更新します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/ba09c756-e8da-40f5-d453-53472cc724b0.png)


```ruby
issues = Issue.where(project_id: 1).where.not(start_date: nil, due_date: nil)

issues.each do |issue|
  # start_dateとdue_dateに3日を足して更新
  new_start_date = issue.start_date + 3.days
  new_due_date = issue.due_date + 3.days

  issue.update(start_date: new_start_date, due_date: new_due_date)
end
```

下図が実行結果です。赤枠のプロジェクトに属しているチケットだけ、開始日と期日が3日遅延して、青枠のプロジェクトは対象外のため、変動がありません。

<img width="100%" alt=" 複数のチケットを一括変更" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/17ca2611-7c47-0531-85ff-82675b18dae0.png">
＜ 複数のチケットを一括変更＞

### 3. 特定のバージョンに属している全てのチケットを指定日数遅延させる方法

「rails console」で下記のコマンドを実行することで、特定のバージョンに属している全てのチケットを指定日数遅延させることができます。
プログラムソースを見ていただくとすぐに分かると思いますが、Issueモデルとfixed_versionをjoinさせて、versionsのIDが10、下図の例示では、バージョン名「6.0.0」に属していて、かつ、開始日と期日に値が登録されているチケットを「issues」という変数で取得します。
issues変数の各要素を取り出して、そのチケットの開始日と期日に指定日数、下記の場合は、3日をプラスして、元々のチケットの開始日と期日としてその値を更新します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/8a375095-aa66-07d2-4527-f8ebe919e0d3.png)


```ruby

issues = Issue.joins(:fixed_version).where(versions: { id: 10 }).where.not(start_date: nil, due_date: nil)

issues.each do |issue|
  # start_dateとdue_dateに3日を足して更新
  new_start_date = issue.start_date + 3.days
  new_due_date = issue.due_date + 3.days

  issue.update(start_date: new_start_date, due_date: new_due_date)
end

```

下図が実行結果です。赤枠のバージョンに属しているチケットだけ、開始日と期日が3日遅延して、青枠のバージョンは対象外のため、変動がありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633321/f9412ea9-d257-1dce-a1ca-67ce2c980478.png)






* * *
## 感想

* 上記の２と３はほぼほぼプログラムソースは同じです。違いは、変更するべき対象チケットが違っているだけです。そのため、このプログラムの肝は変更するべき対象チケットの取得にあります。今回は特定のプロジェクト、特定のバージョンに属している全てのチケットを対象にしましたが、今回の例示以外にも、特定の担当者、特定の日より開始日が遅いチケット、特定のチケットタイトル、特定のカテゴリ、特定のステータスに属するチケットなど、現場のニーズに合わせて、対象チケットの定義だけを変更すれば、それ以降のロジックは同じロジックでプログラムを実行できます。
* プロジェクトは生き物であるため、計画通りにいかない場合が頻繁に発生します。そのためプロジェクト管理ツールであるRedmineもプロジェクトの進捗に合わせて柔軟に、より少ない工数で情報の修正、変更ができる必要がありますが、現状のRedmineには、本記事で紹介した一括でスケジュールを変更させる方法が提供されていません。
* ただし、この方法を行うためにはRedmineへコンソールでアクセスができる必要があり、どの現場でも、誰でもできるわけでは無いのが大きなデメリットです。
* Redmineへコンソールでアクセスができない場合は、JavaScriptを使っても一括で各チケットの開始日と期日を変更させることは可能です。JavaScriptを使って一括で各チケットの開始日と期日を変更させる方法は、チケットの編集権限があるユーザーであれば誰でも実行することができ、実行のハードルは低くなります。（いつか機会がありましたら、ご紹介します。）


* * *
### この記事の作成者の紹介
* * *
山崎進
* Redmine、Jquery、JavaScript,Rails、Ruby、SQL、VBA、RPAの開発を行なっています。
* 自動化、業務の効率化に高い関心があります。
* 下記の媒体で情報を発信しています。Redmineのプラグインの開発などに対応が可能ですので、お気軽にご連絡ください。

　* Qiita：https://qiita.com/ankosoft
　* Twitter：https://twitter.com/yamasaki24
　* Redmine Advent Calendarで記事投稿
　* redmine.tokyoで講演多数
　* Redmine Japan Vol.1 前夜祭、Redmine Japan Vol.3で講演
　* https://ankosoft.co.jp/blog/
　* https://technology.ankosoft.co.jp/

* * *
### 関連記事

 *　[JqueryでRedmineのメニューにアイコンを入れる方法](https://qiita.com/yam_asaki/items/32097598cb0a653dd916)

 *　[JqueryでRedmineのメニューを閉じたり開いたりする方法](https://qiita.com/yam_asaki/items/5ac4a1127beeed53059c)

　*　[JqueryでRedmineの「活動ページ」をもっと便利に(タイトルを開閉したり、曜日を入れたり)](https://qiita.com/yam_asaki/items/718513b52b30b30f65bc)

　*　[JqueryでRedmineの「活動ページ」をもっと便利に②(フィルタリング機能と移動機能)](https://qiita.com/yam_asaki/items/2428610fd89bc73ce0ab)

　*　[JqueryでRedmineの「wikiページ」をもっと便利に(フィルタリング機能と移動機能)](https://qiita.com/yam_asaki/items/a6a32c45dbbc72a28836)

　*　[JqueryでRedmineの「チケットページ」をもっと便利に(年ごと、月ごと、四半期ごとの集計機能の開発)](https://qiita.com/yam_asaki/items/176d07588793b3e66b5d)

　*　[RedmineのパスワードやログインIDを忘れた時の復旧方法](https://qiita.com/yam_asaki/items/6881c92b30dc85f589ad)

　*　[「rails console」を使ってRedmine上のスケジュールを一括変更する方法](https://qiita.com/yam_asaki/items/1d41dc8653773f3522e6)