1. ホーム
  2. Ruby on Rails
  3. Railsでseed-fuを使って初期データを作ろう!

Railsでseed-fuを使って初期データを作ろう!

目次

  1. はじめに
  2. gem seed-fuの導入
  3. 基本の使い方
  4. 関連付け(アソシエーション)
  5. seed_once
  6. シンタックスシュガー(もうひとつの書き方)
  7. CSVからのデータ作成
  8. ユーザー作成時に注意すること
  9. まとめ

はじめに

Railsにはデフォルトで初期データを入れる機能がありますが、実行する度に同じデータが作成されてしまいます。seed-fu を利用するとデータの追加、管理が簡単にできるようになります!

seed_fu のGithubリポジトリ

今回使用する環境

  • Ruby: 2.4.1
  • Ruby on Rails: 5.1.4
  • seed-fu: 2.3.9

gem seed-fuの導入

seed-fu のインストール

まず seed-fu をインストールしましょう。

Gemfile

gem 'seed-fu'

$ bundle install を実行

ディレクトリを作成

次に seed ファイルを置くディレクトリを作成します。

db/fixtures
db/fixtures/development
db/fixtures/production

db/fixtures は必ず必要なディレクトリです。
db/fixtures に作成した seed ファイルを置くこともできますが、db/fixtures/developmentdb/fixtures/production に seed ファイルを作成すると環境ごとに異なるデータを作成することができとても便利です。

POINT!!

db/fixture 以下の seed ファイルはアルファベット順に読み込まれます。読み込む順番を指定する必要がある時は以下のようにファイル名の始めに数字を入れましょう。
01_category.rb
02_sub_category.rb
03_skill.rb

基本の使い方

seed ファイルの作成

db/fixturesに以下のように seed ファイルを作成します。
ここでは例として Category モデルを使っています。

01_category.rb

Category.seed do |s|
s.id = 1
s.name = 'HTML'
end

Category.seed do |s|
s.id = 2
s.name = 'CSS'
end

Category.seed do |s|
s.id = 3
s.name = 'Ruby'
end

seed_fu コマンドの実行

$ rails db:seed_fu を実行

実行結果

== Seed from ./db/fixtures/development/01_category.rb
- Category {:id=>1, :name=>"HTML"}
- Category {:id=>2, :name=>"CSS"}
- Category {:id=>3, :name=>"Ruby"}

これでデータが作成されます!

データの更新

一度作ったデータを更新したい時は、
変更したい部分を修正
01_category.rb

...

Category.seed do |s|
s.id = 3
s.name = 'Ruby on Rails'
end

もう一度$ rails db:seed_fu を実行

実行結果

== Seed from ./db/fixtures/development/01_category.rb
- Category {:id=>1, :name=>"HTML"}
- Category {:id=>2, :name=>"CSS"}
- Category {:id=>3, :name=>"Ruby on Rails"}

このようにデータの更新をする事ができます。

関連付け(アソシエーション)

関連付けのあるデータの作成

has_many などで関連付けがされている場合、どのようにデータを作ればいいでしょう?
HTMLカテゴリーの中に「Webフォントの設定」、「画像の設定」という Skill を作ってみます。

02_skill.rb

Skill.seed do |s|
s.id = 1
s.category = Category.find_by(name: 'HTML')
s.name = 'Webフォントの設定'
end

Skill.seed do |s|
s.id = 2
s.category = Category.find_by(name: 'HTML')
s.name = '画像の設定'
end

$ rails db:seed_fu を実行

実行結果

== Seed from ./db/fixtures/development/02_skill.rb
- SubCategory {:id=>1, :category=>#, :name=>"Webフォントの設定"}
- SubCategory {:id=>2, :category=>#, :name=>"画像の設定"}

このように関連付けのあるデータを作成する事ができます。

seed_once

seedメソッドだと??

rails db:seed_fuを実行すると、毎回データの作成または更新が行われます。

例えば、
seed ファイルを作成

Category.seed do |s|
s.id = 1
s.name = 'HTML'
end

$ rails db:seed_fu を実行

railsアプケーションやコンソール上でカテゴリーの名前を「HTML」から「html」に変更して
もう一度$ rails db:seed_fu を実行

実行結果

== Seed from ./db/fixtures/development/01_category.rb
- Category {:id=>1, :name=>"HTML"}

カテゴリーの名前は「HTML」に書き換えられます。

seed_onceを使う

一度データを作成した後は更新したくない場合、 seed_onceを使います。

先ほどと同じように、
seed ファイルを作成(今回はseed_onceを使います。)

Category.seed_once do |s|
s.id = 1
s.name = 'HTML'
end

$ rails db:seed_fu を実行

railsアプケーションやコンソール上でカテゴリーの名前を「HTML」から「html」に変更して
もう一度$ rails db:seed_fu を実行

Category.seed_once do |s|
s.id = 1
s.name = 'HTML'
end

実行結果

== Seed from ./db/fixtures/development/01_category.rb

一度作成したデータなので何も起きず、カテゴリーの名前は「html」のままになります。
(デフォルトでは作成したデータかどうかのチェックに ID を利用します。)

シンタックスシュガー

シンタックスシュガーを使ってみる

seedファイルを作成する時は、これまでのような記述の他に以下のように記述することもできます。

Category.seed(:id,
{ id: 1, name: 'HTML' },
{ id: 2, name: 'CSS' },
{ id: 3, name: 'Ruby' },
)

$ rails db:seed_fu

実行結果

== Seed from ./db/fixtures/development/01_category.rb
- Category {:id=>1, :name=>"HTML"}
- Category {:id=>2, :name=>"CSS"}
- Category {:id=>3, :name=>"Ruby"}

同じようにデータが作成されます。

CSVからのデータ作成

CSVファイルからデータを作成してみる

まずはCSVファイルを作る(ここではid, name の順。要素をカンマで区切ればOKです!)

db/fixtures/development/category.csv

1,HTML
2,CSS
3,Ruby

seedファイルにCSVから読み込む処理を書く
db/fixtures/development/01_category.rb

require 'csv'

csv = CSV.read('db/fixtures/development/category.csv')
csv.each do |category|
Category.seed do |s|
s.id = category[0]
s.name = category[1]
end
end

先ほど csvファイルには id, name の順に記述しました。
なので、category[0]id, category[1]name になります。

$ rails db:seed_fu

実行結果

== Seed from ./db/fixtures/development/01_category.rb
- Category {:id=>1, :name=>"HTML"}
- Category {:id=>2, :name=>"CSS"}
- Category {:id=>3, :name=>"Ruby"}

これでCSVファイルからデータを作成することができました!
大量のデータを作る時などに便利ですね。

ユーザー作成時に注意すること

device や sorcery を使っていると…

Railsアプリケーションの user には大抵 devise や sorcery を使った認証機能が実装されているのではないかと思います。

そのようなユーザーをこのように作ると…
00_user.rb

User.seed do |s|
s.id = 1
s.name = 'yuh'
s.email = 'sample@test.com'
s.password = 'password'
s.password_confirmation = 'password'
end

$ rails db:seed_fu

実行結果

== Seed from ./db/fixtures/development/00_user.rb
User {:id=>1, :name=>"yuh" :email=>"sample@test.com", :password=>"password", :password_confirmation=>"password"}

エラーも発生しないし、うまくいった 気がする!

しかし、
作成された user を確認してみると…

<User id: 1, name: "yuh", email: "sample@test.com", crypted_password: nil, salt: nil, created_at: "2018-06-22 01:36:04", updated_at: "2018-06-22 01:36:04">

!???
crypted_password: nil, salt: nil
パスワードが設定されていない!

POINT!!

通常のユーザー作成の手順ではパスワードを暗号化して crypted_password などが作成されます。
しかし、seed-fu ではこの処理は行われずそのままのデータを作成しようとします。
そのためパスワードが正しく設定されません。

ユーザーを作るときは?

このような時はデフォルトの seed を使いましょう。
00_user.rb

User.create!(id: 1, name: 'yuh', email: 'sample@test.com',
password: 'password', password_confirmation: 'password')

$ rails db:seed_fu

実行結果

== Seed from ./db/fixtures/development/00_user.rb

何も表示されませんが、作成された user を確認してみると…

<User id: 1, name: "yuh", email: "sample@test.com", crypted_password: "a$e7g2uKH8eoWYo.zmnTYcJOOF4gbs0g8egWfDwH6aPQy...", salt: "RvQfSMBKboxwzBEZ8Sv5"

きちんとパスワードが設定されています!

まとめ

初期データセットのためのgem、 seed-fu の使い方を見てきました。
seed-fu を利用するとデータの追加、管理が簡単にできるようになります!

ユーザー作成の時には注意が必要ですが(私はユーザー作成でハマりました…)使い方は難しくないと思います。
初期データを作成する時はぜひ使ってみてください!

Author Profile

はらた
はらた
サーバーサイドエンジニア
Ruby on Railsを使った開発を行なっています

この記事は
参考になりましたか?

PAGE TOP