seedを使ってデータを自動で生成する

f:id:endoakak:20200727195635j:plain

アプリを製作する時に、とりあえずデータベースにデータを保存して挙動を確認したい、ということがあると思います。

ビューできちんと表示されるかな、みたいな。

手動でデータを作成することももちろん可能ですが、seedを使うことで簡単に仮のデータを作成できます。

seedの使い方

全体的な流れとしては、

seeds.rbにデータを記述しておく

ターミナルでrails db:seed

という感じです。シンプル。

では実際に使ってみます。Rails newで新規アプリを作成して、nameとpriceというカラムを持ったItemsテーブルを作成しました。

そして、dbディレクトリにseeds.rbというファイルがあるので、データを記述します。

Item.create(name: "pen", price: 100)
Item.create(name: "notebook", price: 120)
Item.create(name: "textbook", price: 1000)

これで、ターミナルでseedファイルを実行すればOKです。

% rails db:seed

f:id:endoakak:20200813091707p:plain:w200

簡単にレコードを生成することができました。

より効率的に記述する

rails db:seedのコマンド一つでレコードを生成できるのは便利です。しかし、そのための記述をseedファイルに書き込むのはめんどくさい。レコードの数が少なければいいですが、大量のレコードを生成したい場合、もっと効率よく作りたいですね。

timesメソッドを使う

timesメソッドを使えば、レコードを10個でも100個でも簡単に生成できます。

db/seeds.rbに、このように記述しました。

10.times do |i|
  Item.create(name: "sample#{i}", price: 100 * i)
end

これでseedを実行すれば

% rails db:seed

f:id:endoakak:20200813185440p:plain:w200

レコードが10個できました。

レコードが100個必要ならtimesの前の数字を100に変えるだけです。

ユーザーに紐づいたアイテムを作る

少しだけ複雑にしてみます。ユーザーのレコードを生成して、それに紐づいたアイテムのレコードを生成してみます。

カラムがnameだけのusersテーブルを作成し、itemsテーブルにはuser_idカラムを追加しました。Userモデルにはhas_many :items、Itemモデルにはbelongs_to :userでアソシエーションを設定してあります。

class User < ApplicationRecord
  has_many :items
end
class Item < ApplicationRecord
  belongs_to :user
end

db/seeds.rbには以下のように記述しました。

User.create(name: "sato")
User.create(name: "tanaka")

User.all.each_with_index do |user, i|
  user.items.create(name: "bag#{i}", price: 1000 * i)
end

これでseedを実行すると、

% rails db:seed

users

f:id:endoakak:20200813191913p:plain:h100

items

f:id:endoakak:20200813191934p:plain:h100

ユーザーと、ユーザーに紐づいたアイテムをまとめて生成できました。

ユーザーを生成した後に、eachメソッドを使って各ユーザーに対してアイテムを生成していけばOKですね。

timesメソッドも組み合わせれば、一人のユーザーに対して複数のアイテムを作ったりも出来そうです。

まとめ

  • seedを使うと簡単にデータを生成できる
  • 大量のレコードを生成したいときはtimesメソッドを使うと便利
  • アソシエーションが設定されていても使える