Rails
Gem
seed-fu

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

More than 1 year has passed since last update.

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に記述する

Gemfile
gem 'seed-fu', '~> 2.3'

そして、インストール

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

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

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

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

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モデルに対して設定するケース。

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ディレクトリのみを対象としたい。

ディレクトリを指定して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に記述されている
都道府県モデルに対するデータのみを対象とするケース。

モデルを指定して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」の使い方 (2012)

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