##はじめに
先日初めてseedsを使い初期データを登録しましたが、docker-compose up
の度にデータが作成されてしまい、気づいたらデータ数がとんでもないことになっていました...。
解決できたのでメモしておきます。
##seedsに初期データを書く
今回はname
,age
,hobby
のカラムを持つusersテーブルに3つ、初期データを登録していきます。
User.create!(
[
{
name: 'Mary',
age: 22,
hobby: 'Cooking'
},
{
name: 'Alice',
age: 25,
hobby: 'Basketball'
},
{
name: 'John',
age: 28,
hobby: 'Soccer'
}
]
)
これでrake db:seed
を実行するとデータが作られます。
##Docker起動時にデータを作成する
docker-compose up
で自動的にデータが作られるように、docker-entrypoint.sh
に加筆しました。
set -eu
bundle exec rails db:create
bundle exec rails db:migrate
#以下を加筆
bundle exec rails db:seed
これで無事に初期データが作られました。
……しかし!
#####これではDockerを起動する度にデータが作られてしまうのです。
###重複を防ごうとやってみたこと
・idを振ってcreate
にしてみる
→id重複のエラー。
・idを振って、create!
をfind_or_create_by
にしてみる
User.find_or_create_by(
[
{
id: 1,
name: 'Mary',
age: 22,
hobby: 'Cooking'
},
{
id: 2,
name: 'Alice',
age: 25,
hobby: 'Basketball'
},
{
id: 3,
name: 'John',
age: 28,
hobby: 'Soccer'
}
]
)
これだと、TypeError: no implicit conversion of Hash into String
エラーが出てしまいました。
##first_or_createで解決
色々調べながら、first_or_create
を使ってみました。
User.first_or_create(
[
{
id: 1,
name: 'Mary',
age: 22,
hobby: 'Cooking'
},
{
id: 2,
name: 'Alice',
age: 25,
hobby: 'Basketball'
},
{
id: 3,
name: 'John',
age: 28,
hobby: 'Soccer'
}
]
)
2回目以降dockerを立ち上げても、データが重複して作られることはありませんでした。id無しでも試してみましたが、データの重複が無いことを確認できました。
first_or_create
は既に同じデータがある場合は作成せず、無ければ新たにデータを作ってくれる。find_or_create_by
も同じようなメソッドな気がしていたのですが…
##まとめ
・docker起動時にseedsでデータを挿入するにはdocker-entrypoint.sh
に加筆する。
・データの重複を防ぐにはfirst_or_create
を使う。
初心者ですので、間違っている点や他の方法等あればご指摘いただけますと幸いです。