2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Redmineのテスト・デモデータ管理にRailsのフィクスチャ(fixture)を利用してみる

Posted at

この記事は、Redmine Advent Calendar 2024 の9日目の内容になります。

はじめに

Redmineでは運用時のデフォルトデータの読み込みに load_default_data タスク、開発時のテストデータの読み込みにはRailsの db:fixtures:load タスクを利用することが多いと思います。

ただ、Redmineでテスト・デモ用に個別にカスタマイズしたデータを保存・復元できると、間違った操作を行ってしまった場合も簡単に元の状態に復元でき、YAML形式のフィクスチャファイルの編集・コード管理もできて便利なように思いましたので、少し調べてみました。

データベースの内容をフィクスチャ(fixture)に保存する

最初は以下のStack Overflow記事を参考に、モデルベースで進めようとしてましたが、

Active Recordの has_and_belongs_to_many (多対多)関連付けとなっているテーブル(projects_trackers など、rake db:migrate 後の db/schema.rb 内で id: false のもの)の保存に対応できず、断念しました...。

どうしたものかと考えていたところ、Redmineの lib/tasks フォルダ内に extract_fixtures.rake という古いタスクがあり、データベース内のテーブルベースで上記の多対多関連付けテーブルも問題なさそうでしたので、こちらを新しいRailsでも動作するよう修正してみました。

1つ目のパッチがメインの修正で、ヘッダのライセンスコメントを除くコード部分は以下となります。

lib/tasks/extract_fixtures.rake
desc 'Create YAML test fixtures from data in an existing database.
Defaults to development database. Set RAILS_ENV to override.'

task :extract_fixtures => :environment do
  dir = ENV['DIR'] || './tmp/fixtures'
  FileUtils.mkdir_p(dir)

  sql = "SELECT * FROM %s"
  skip_tables = ["schema_migrations", "ar_internal_metadata"]
  ActiveRecord::Base.establish_connection
  (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
    i = "000"
    File.open(File.join(dir, "#{table_name}.yml"), 'w') do |file|
      data = ActiveRecord::Base.connection.select_all(sql % table_name)
      file.write data.inject({}) { |hash, record|
        # cast extracted values
        ActiveRecord::Base.connection.columns(table_name).each { |col|
          record[col.name] = ActiveRecord::Type.lookup(col.type).deserialize(record[col.name]) if record[col.name]
        }
        hash["#{table_name}_#{i.succ!}"] = record
        hash
      }.to_yaml
    end
  end
end

上記のコードをコピーして、Redmineの lib/tasks/extract_fixtures.rake ファイルのコード部分に上書きすれば、以下のようにコマンドを実行することで、データベースの内容をフィクスチャに保存することができます。

bundle exec rake extract_fixtures DIR=(保存先ディレクトリ (デフォルト: ./tmp/fixtures))

保存したフィクスチャを読み込む

保存したフィクスチャを読み込むには以下を実行します。

bundle exec rake db:fixtures:load FIXTURES_PATH=(保存先ディレクトリ)

なお、フィクスチャの読み込み時には、データベース内のテーブル内容が削除されますので、間違って本番環境データを削除したりすることがないよう、十分注意してください。

参考リンク

注意事項

  • 上述のパッチですが、まだ提案段階なので、今後レビューなどで仕様が変わるかもしれません :bow:
  • テスト・デモ用の軽めのデータ量を想定しています。大量のデータが含まれる場合は、YAML形式ではファイル容量が増大するので、CSV形式など、別のファイル形式に保存・復元するrakeタスク作成が必要かもしれません
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?