Railsアプリケーションで初期データをセットアップする方法あれこれ


## はじめに

本記事では、Railsアプリケーションにおける初期データのセットアップ方法の基本から、知っておくと少し役立つTipsを紹介します。具体的には、以下の内容です。

- データセットアップ手順の基本
- データセットアップのTips
    - ロード先の環境を指定する方法
    - 環境ごとにロードするデータを分ける方法
    - データを消してから再ロードする方法
    - ファイルからデータをロードする方法（CSV・JSON）

## データセットアップ手順の基本

以下のカラムを持つ「Members」テーブルに初期データをセットアップしたいとします。

|カラム名|型|
|---|---|
|member_id|string|
|name|string|
|age|integer|
|created_at|datetime|
|updated_at|datetime|

### 1.seeds.rbを編集する

`rails new`コマンドでRailsプロジェクトを作成すると、**`db/seeds.rb`**というファイルが自動生成されているはずです。

このファイルにデータセットアップするためのコードを記述します。ちなみに`seeds.rb`には初期状態でコメントが記述されているかと思いますが、このコメントは削除してもしなくてもOKです。

今回は、ActiveRecordの`create!`メソッドを使います。後述する`rake db:seed`というコマンドを実行すると、`seeds.rb`に記述したこれらの処理が実行されます。

※`create`はバリデーションエラー時にnilを返しますが、`create!`はエラーになります。

```db/seeds.rb
# coding: utf-8

Member.create(member_id: '001', name: 'ウッディ', age: 25)
Member.create(member_id: '002', name: 'バズ', age: 30)
Member.create(member_id: '003', name: 'リトルグリーンメン', age: 999)
```

### ２．rake db:seedを実行する

では、`rake db:seed`を実行してみましょう。

```
$ rake db:seed
$ rails db

sqlite> select * from Members;
1|001|ウッディ|25|2019-07-08 12:35:46.734420|2019-07-08 12:35:46.734420
2|002|バズ|30|2019-07-08 12:35:46.738636|2019-07-08 12:35:46.738636
3|003|リトルグリーンメン|999|2019-07-08 12:35:46.741150|2019-07-08 12:35:46.741150
```

`seeds.rb`に記述したレコード保存処理が実行され、3レコードが保存されていることが確認できました。

まとめると、

1. `db/seeds.rb`にレコードを保存する処理を記述する
2. `rake db:seed`コマンドを実行する

この2ステップがデータセットアップの基本になります。

## データセットアップのTips

ということで、基本だけ知っていればとりあえず初期データを投入することができますが、更に知っておくと便利なTipsを紹介します。

### ロード先の環境を指定する

```
$ rake db:seed RAILS_ENV=test
```

`RAILS_ENV`オプションを指定するとロード先の環境を指定することができます。テスト環境にロードする場合は`RAILS_ENV=test`となります。

オプションを指定しないとdevelopment環境にロードされます。

### データを消してから再ロードする

`rake db:migrate:reset`コマンドでロードされているデータをリセット（削除）することができます。

再ロードする場合は続けて`rake db:seed`すればOKです。

### 環境ごとにロードするデータを分ける

環境ごとにロードするデータを分けて準備することも可能です。

`db/seeds.rb`の内容を以下に書き換えます。

```db/seeds.rb
load(Rails.root.join('db', 'seeds', "#{Rails.env.downcase}.rb"))
```

次に**`db/seeds/環境名.tb`**というファイルを新たに作成し、レコード保存の処理を記述します。test環境にロードする場合、`db/seeds/test.rb`というファイルになります。

```db/seeds/test.rb
# coding: utf-8

Member.create(member_id: '001', name: 'ウッディ', age: 25)
Member.create(member_id: '002', name: 'バズ', age: 30)
Member.create(member_id: '003', name: 'リトルグリーンメン', age: 999)

```

そして`rake db:seed RAILS_ENV=test`を実行すると、`db/seeds/test.rb`に記述した通りにtest環境にデータがロードされます。

同じように`db/seeds/development.rb`、`db/seeds/production.rb`のように**`db/seeds/環境名.tb`**というファイルを用意することで、環境ごとにロードするデータを分けることができます。

参考： [環境ごとに投入する初期データを変える](https://qiita.com/kimihito_/items/753390a5fe42a41b1d60)

## ファイルからデータをロードする方法

ファイルに記述したデータからセットアップすることもできます。

### CSVファイルからロードする

CSVからロードする場合、以下のようにCSVファイルのデータを参照して`create`するように記述します。

```db/sample.csv
'001','ウッディ',25
'002','バズ',30
'003','リトルグリーンメン',999
```

```db/seeds.rb
require "csv"

CSV.foreach('db/sample.csv') do |row|
  Member.create(member_id: row[0], name: row[1], age: row[2])
end
```

`require "csv"`を忘れずに！

### JSONファイルからロードする

JSONファイルからもロードできます。

```db/sample.json
[
  {
    "member_id": "001",
    "name": "ウッディ",
    "age": 25
  },
  {
    "member_id": "002",
    "name": "バズ",
    "age": 30
  },
  {
    "member_id": "003",
    "name": "リトルグリーンメン",
    "age": 999
  }
]
```

```db/seeds.rb
json = ActiveSupport::JSON.decode(File.read('db/sample.json'))

json.each do |data|
    Member.create(member_id: data['member_id'], name: data['name'], age: data['age'])
end
```

## まとめ

以上です。基本的には以下の2ステップでロードできます。簡単ですね！

1. `db/seeds.rb`にレコードを保存する処理を記述する
2. `rake db:seed`コマンドを実行する