seed-fu を使い、Rails上で使うデータを設定する話

Rails上で初期データをセットするときに、seed-fuというgemが有効そうだったので使用する話。

# 動機

Railsアプリを作るときに、変更する機会が少ない初期データは、
`rake db:seed` で読み込ませるのが良さそう・・・な気がした。
が、細かい設定がしづらい。

そこで、Railsで使うDBにデータをセットするgem `seed-fu` を使って
実施してみた。

# 実施内容

seed-fu をインストールする。

不動産情報サイトと仮定し
物件種類、契約データをrubyファイルに直書き、
都道府県データをCSVから読み込んで登録。

## seed-fu の github はこちら

https://github.com/mbleigh/seed-fu

# 環境

いつものやつですが。Railsのバージョンが3.1未満だったりすると若干変わってきます。

- Rails 4.2.6
- ruby 2.2.3
- DBはSQLite3
- gemはbundler 使って個別にインストールする派
- パスは vendor/bundle

都道府県と物件種類、契約状況のオブジェクトはすでに存在し
以下のようなデータ構造を持つと仮定します。

都道府県　id:integer name:string
物件種類　id:integer name:string
契約状況　id:integer name:string

全部構造同じじゃないか！というツッコミが来そうですが、
idをプログラム上で識別するための値、nameを人間が識別するための値で、
最低限のデータで表現。
 

# gemで取得する

githubの記述に基づき　Gemfileに記述する

```ruby:Gemfile
gem 'seed-fu', '~> 2.3'
```

そして、インストール

```bash:インストールコマンド
$ bundle install --path vendor/bundle
```

#フィクスチャファイルを用意する


データをDBに入れる処理を記載するフィクスチャファイルの配置場所は、Railsプロジェクトのルートから見て`db/fixtures`ディレクトリ以下（fixtureディレクトリ以下に、さらにディレクトリを作って分けることも可能）

ここでは、データを外部から参照しないケースとするケース、両方を取り上げます。

## Rubyスクリプトファイルに直接記述

項目数が少なかったり、入力する値をスクリプトで生成するケースに有効そう。

一つのファイルに、複数のモデルのデータに関する設定を記述することも可能。

```ruby:params.rb


Home.seed do |s|
  s.id = 1
  s.name = '新築戸建'
end

Home.seed do |s|
  s.id = 2
  s.name = '中古戸建'
end

Home.seed do |s|
  s.id = 3
  s.name = '新築マンション'
end

Home.seed do |s|
  s.id = 4
  s.name = '中古マンション'
end

Status.seed do |s|
  s.id = 1
  s.name = '表示'
end

Status.seed do |s|
  s.id = 2
  s.name = '非表示'
end

```

テキトーな内容ですが、状態を区別するような項目であればこんな書き方で十分と思います。

## CSV（スプレッドシート）をインポート

モデルに対して投入するデータの項目数が、すでに用意されているケースなどで有効です。ここでは、あらかじめ用意されている都道府県データをprefモデルに対して設定するケース。

```ruby:prefs.rb
require 'csv'

csv = CSV.read('db/fixtures/pref_src.csv')

csv.each_with_index do |pref, i|
  # skip a label row
  next if i === 0

  name = pref[1]

  Pref.seed do |s|
    s.id   = i
    s.name = name
  end
end

```

CSV読み込んでeachして（見出しのある最初の行はスルーして）、
Prefモデルに対して、延々とid を行番号、名前を入力していく処理。

# 読み込むCSVデータを用意する

CSVデータどうしようかな・・・と思ったら、あった。
しかも自由に使用可能とのこと。

csv/excel/コピペ用 都道府県コード一覧　データ分析とインテリジェンス

http://analysis-intelligence.net/?no=31

都道府県コード(UTF-8).csv　をリネームして使用することにしました。

なお、このファイルは以下のような内容です
```csv:読み込む都道府県データ
コード,都道府県
01,北海道
02,青森県
（中略）
46,鹿児島県
47,沖縄県
```

# seed-fuの実施

` rake db:seed_fu` と、オプションを指定せずに処理を開始すると、
フィクスチャフォルダ以下にあるrubyスクリプトファイルをすべて読み、DBに書き込もうとします。

実際の使い方は、特定のモデルだけ対象にしたいなどのケースが多いとおもう。

## 特定のディレクトリ配下の内容のみ、対象とする

ディレクトリ別に指定することも可能です。
仮に、　`db/fuxtures`の配下にある`sample`ディレクトリのみを対象としたい。

```bash:ディレクトリを指定してseed_fuを実施
$ bundle exec rake db:seed_fu FIXTURE_PATH=./db/fixtures/sample

== Seed from ./db/fixtures/sample/params.rb
 - Home {:id=>1, :name=>”新築戸建”}
 - Home {:id=>2, :name=>”中古戸建”}
 - Home {:id=>3, :name=>”新築マンション”}
 - Home {:id=>4, :name=>”中古マンション”}
 - Status {:id=>1, :name=>”公開”}
 - Status {:id=>2, :name=>”非公開”}
```

## 特定のモデルを対象とする

`db/fixtures` ディレクトリに存在する　pref.rbに記述されている
都道府県モデルに対するデータのみを対象とするケース。

```bash:モデルを指定してseed_fuを実施
$ bundle exec rake db:seed_fu FILTER=prefs

 - Pref {:id=>1, :name=>"北海道"}
 - Pref {:id=>2, :name=>"青森県"}
 - （中略）
 - Pref {:id=>46, :name=>"鹿児島県"}
 - Pref {:id=>47, :name=>"沖縄県"}
```

# 参考

[Ruby on Rails] seedデータの追加や管理をカンタンにしてくれる「seed-fu」の使い方　（２０１２）

http://codenote.net/ruby/rails/1635.html