Rails上で初期データをセットするときに、seed-fuというgemが有効そうだったので使用する話。
動機
Railsアプリを作るときに、変更する機会が少ない初期データは、
rake db:seed
で読み込ませるのが良さそう・・・な気がした。
が、細かい設定がしづらい。
そこで、Railsで使うDBにデータをセットするgem seed-fu
を使って
実施してみた。
実施内容
seed-fu をインストールする。
不動産情報サイトと仮定し
物件種類、契約データをrubyファイルに直書き、
都道府県データをCSVから読み込んで登録。
seed-fu の github はこちら
環境
いつものやつですが。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に記述する
gem 'seed-fu', '~> 2.3'
そして、インストール
$ bundle install --path vendor/bundle
フィクスチャファイルを用意する
データをDBに入れる処理を記載するフィクスチャファイルの配置場所は、Railsプロジェクトのルートから見てdb/fixtures
ディレクトリ以下(fixtureディレクトリ以下に、さらにディレクトリを作って分けることも可能)
ここでは、データを外部から参照しないケースとするケース、両方を取り上げます。
Rubyスクリプトファイルに直接記述
項目数が少なかったり、入力する値をスクリプトで生成するケースに有効そう。
一つのファイルに、複数のモデルのデータに関する設定を記述することも可能。
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モデルに対して設定するケース。
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/コピペ用 都道府県コード一覧 データ分析とインテリジェンス
都道府県コード(UTF-8).csv をリネームして使用することにしました。
なお、このファイルは以下のような内容です
csv:読み込む都道府県データ
コード,都道府県
01,北海道
02,青森県
(中略)
46,鹿児島県
47,沖縄県
seed-fuの実施
rake db:seed_fu
と、オプションを指定せずに処理を開始すると、
フィクスチャフォルダ以下にあるrubyスクリプトファイルをすべて読み、DBに書き込もうとします。
実際の使い方は、特定のモデルだけ対象にしたいなどのケースが多いとおもう。
特定のディレクトリ配下の内容のみ、対象とする
ディレクトリ別に指定することも可能です。
仮に、 db/fuxtures
の配下にあるsample
ディレクトリのみを対象としたい。
$ 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に記述されている
都道府県モデルに対するデータのみを対象とするケース。
$ 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)