seeds.rbの使い方とマスタデータの取り扱いついて考える
1. マスタデータの扱いについて
rake db:seed
するたびにデータが挿入される。
idをインクリメントで自動挿入するときにめんどくさいことになる。
最初に挿入するマスターデータにassociationを張っている場合は、何回も生成してidが更新されると致命的なのでなんとかしたい。
以前はmigrationファイルに書く方法が主流だったみたいだけど、このseeds.rbが2.3.4で追加された理由は「スキーマの生成とDBへの実データの投入は書くところ分けようぜ!」って話だったわけだしmigrationファイルに書いちゃったらマスタ変更したいときに結構無理ゲーになってきそうな感じはある。
方法としては、seed-fuを使うか、seeds.rbで毎回シーケンスをdeleteしてからデータを挿入し直すようにするか
seed-fuはdb/fixtures
という新しいディレクトリを最低限作らないといけないので、それに抵抗がある。チーム全体でseeds.rbを使わないようにしてそちらに合わせてもらうようにするか、それかseeds.rbとseed-fuの使い分け方をきちんと明確にしておかないといけないことになると思う。それは結構めんどい。
といろいろ考えてたら以下でいい感じの方法が。
Railsでdb:seedでマスターテーブルを管理するオススメのやり方
http://d.hatena.ne.jp/JironBach/20131011/1381485761
なるほどidの値も含めてfirst_or_create
を呼べばいいのか。
ってこれならfirst_or_create
じゃなくてfind_or_create
でも一緒では、って思ったら、どうやらfirst_or_create
はdeprecateになるらしい。
ということでそちらを使って書くことに。例えばこんな感じかな。
Origin.find_or_create_by { name: "Original Blend" }
今までの分をリセットするには
$ bin/rake db:reset
すればok。別にdropするのは同じなので、associationとかを追加してない限りdb:migrate:reset
する必要はないかな。
2. seeds.rbをキレイに書きたい。
seeds.rbが長くなりがちなのでキレイに書きたい。
seeds.rbはただのRubyスクリプトなのでどんな書き方でもいいんだけど、だからこそみんなで統率がとれなくなりがちだ。
特にマスタデータに関しては初期で大量のデータが入る可能性もあると思うので。ここにやり方が書いてあるけど、まだ冗長な感じがする。
seeds.rbをスッキリさせる3つのポイント
http://blog.interfirm.co.jp/entry/2014/05/30/195044
以下も参考に。
Rails 2.3.4で追加されたseeds.rbについて
http://higelog.brassworks.jp/?p=350
いちいちハッシュを作ってるとDRYにならないのでほんとは以下のように書きたい。
%w{テント 寝袋}.each do |name| Category.create(:name => name) end
要素は一行に一つと決めたら、編集もしやすいかなということでそんな感じで書くことにしてみた。%w
は一文字スペースじゃなくて改行で配列を作ってくれるので。
こんな感じのコードが、
Origin.create([{ name: "Kenya" }, { name: "Rwanda" }, { name: "Ethiopia" }, { name: "Brazil" }, { name: "Costalica" }, { name: "Indonesia" }, { name: "Tanzania" }])
最終的にこんな感じになりました。originsに一回入れるかは迷ったけど、上から読んでいったときにこちらの方がわかりやすいと思ったのと、最後に.each
をくっつけるとなんか気持ち悪かったので。
origins = %w( Kenya Rwanda Ethiopia Brazil Costalica Indonesia Tanzania ) origins.each do |origin| Origin.find_or_create_by(name: origin) end
2つ以上の要素を突っ込みたいときは以下の方法でできそう。
Rubyにて複数の配列を同時にeachする方法