16
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Rails seedsでdocker起動時に初期データを登録する 。データの重複はfirst_or_createで防ぐ】

Last updated at Posted at 2019-08-02

##はじめに
先日初めてseedsを使い初期データを登録しましたが、docker-compose upの度にデータが作成されてしまい、気づいたらデータ数がとんでもないことになっていました...。
解決できたのでメモしておきます。

##seedsに初期データを書く
今回はname,age,hobbyのカラムを持つusersテーブルに3つ、初期データを登録していきます。

db/seeds.rb
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に加筆しました。

etc/docker/rails/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にしてみる

db/seeds.rb
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を使ってみました。

db/seeds.rb
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を使う。

初心者ですので、間違っている点や他の方法等あればご指摘いただけますと幸いです。

16
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?