Railsにおけるマスタデータの投入方法について、いくつかの選択肢があります。 ここでは代表的な seed-fu を用いる方法について、選定理由なども交えて説明します。

前提条件

マスタデータの投入において、今回は以下の条件を満たすものを対象とします。

  • べき等性の担保が容易であること
    • 何度投入を実行しても同じ結果が得られること
  • メンテナンスしやすいこと
  • Railsのレールから外れ過ぎないこと
  • デプロイツールと連携しやすいこと

選択肢

seeds.rb に書く

Railsには標準で db/seeds.rb というファイルがあり、ここにマスタデータを書くのが一般的な方法です。

ただ、べき等性の担保を自分でしなければなりません。 また、単一ファイルのため、開発が進むにつれてファイルが肥大化するという問題もあります。

Rakeタスクを書く

タスクとして書くことで、投入処理を柔軟に記述することができます。

一方で、チーム独自の書き方になってしまうので、分かりづらくなりやすいという問題もあります。 設計やドキュメント化をしっかりとできればよいですが、そうでない場合は避けた方がいいでしょう。

Migrationに書く

seeds.rb が実装される以前の一般的なやり方です。 マイグレーションファイルの self.up に必要なデータを投入する方法で、今でもOSSなどで散見します。

ただ、あくまでMigrationはスキーマを定義するためにあり、データとは切り離すべきでしょう。 また、ここに書いてしまうと、後々の変更も難しくなってしまいます。

ActiveHashを導入する

ActiveHash を用いれば、静的データをActiveRecord継承クラスと同じように扱えます。

ただ、モデルの責務はあくまで抽象化であり、実データを持つべきではないでしょう。 また、このGemの場合、SQLに柔軟に対応できないという問題もあります。

seed-fuを導入する

seed-fu は、seeds.rb の問題を解決し、またCapistranoとの連携も容易に実現できます。

以上の理由より、今回はseed-fuを選びました。

使い方

1. インストールする

Gemfile に追加して bundle install を実行します。

gem 'seed-fu'

2. ディレクトリを作成する

db/fixtures を作成します。 シードファイルはこのディレクトリ下に追加してくことになります。

3. シードファイルをつくる

あとは、必要に応じてシードファイルを作成します。 たとえば、ユーザを作成する場合は以下のようになります。

db/fixtures/user.rb:

User.seed do |s|
  s.role = :member
end

また、管理ユーザのように「1度作成したら上書きしたくない」といった場合、 #seed_once を用います。

db/fixtures/admin.rb:

Admin.seed_once do |s|
  s.id = 1
  s.email = 'user@example.com'
  s.password = 'test1234'
end

4. 投入する

データを投入するには、 db:seed_fu タスクを実行すればよいです。

$ rake db:seed_fu

Capistranoと連携する

seed-fuには、Capistranoによるデプロイ時に投入タスクを実行するための連携用スクリプトも内包されています。

Capfile:

require 'seed-fu/capistrano3'

config/deploy.rb:

before 'deploy:publishing', 'db:seed_fu'

これにより、デプロイの度にマスタデータをべき等に投入することができます。