今回達成すること
ユーザーテーブルにSeedデータを投入します。
また、「開発」「テスト」「本番」の3つの環境でSeedデータを切り替える方法もご紹介します。
Seedデータとは?
Seedデータとは、テーブルに保存するデモデータのことです。
このデータはアプリケーションの動作確認用データとして扱われます。
Seedデータは、Railsの
環境ごとにSeedデータを切り替える
「開発環境にデモデータを投入したいけど、本番環境にはデータは投入したくない」
「テスト環境だけ大量にデモデータを投入したい」
など、環境ごとにデータを切り替えたい場面があります。
ただその都度データ生成用のコードを書き換えるのは大変。。。
そこで「開発」「テスト」「本番」の3つのディレクトリを用意し、環境ごとに読み込むファイルを切り替える設定を行います。
環境ごとのディレクトリを作成する
まずは「db」ディレクトリに「seeds」ディレクトリを作成し、その中に環境ごとのディレクトリを作成します。
root $ mkdir api/db/seeds && mkdir $_/{test,development,production}
ディレクトリ構造は以下のようになりました。
api/db
├── migrate
│ └── 20200708014630_create_users.rb
├── schema.rb
├── seeds
│ ├── development
│ ├── production
│ └── test
└── seeds.rb
seeds.rbの編集
続いて
api/db/seeds.rb
table_names = %w(
users
)
table_names.each do |table_name|
path = Rails.root.join("db/seeds/#{Rails.env}/#{table_name}.rb")
# ファイルが存在しない場合はdevelopmentディレクトリを読み込む
path = path.sub(Rails.env, "development") unless File.exist?(path)
puts "#{table_name}..."
require path
end
table_names = %w(users)
まず読み込みたいファイル名の配列を作成します。
> table_names
=> ["users"]
path = Rails.root.join("db/seeds/#{Rails.env}/#{table_name}.rb")
配列をループしてファイルパスを作成します。
> path
=> #<Pathname:/app/db/seeds/development/users.rb>
Rails.env
今現在の環境を文字列で返します。
> Rails.env
=> "development"
unless File.exist?(path)
パスにファイルが存在しない場合
> File.exist?(path)
=> false
path = path.sub(Rails.env, "development")
「development」ディレクトリを参照するようpath
を書き換えます。
> path
=> #<Pathname:/app/db/seeds/development/users.rb>
puts "#{table_name}..."
現在の読み込みファイルをターミナルに出力します。
> puts "#{table_name}..."
users...
require path
Rubyのrequire
メソッドでファイルを読み込みます。
require path
以上で環境ごとに読み込むファイルを切り替えることができます。
(コラム)文字列書き換えメソッド「sub」と「gsub」の違い
sub
... 最初に一致した文字列を書き換えます。gsub
... gはグローバルの略で一致する全ての文字列を書き換えます。
"abcabc".sub(/abc/, "")
=> "abc"
> "abcabc".gsub(/abc/, "")
=> ""
(コラム終わり)
Seedデータ生成ファイルを作成する
ユーザーSeedデータを生成する
今回は「development」ディレクトリ直下だけに作成します。
root $ touch api/db/seeds/development/users.rb
10人のユーザーを生成します。
api/db/seeds/development/users.rb
10.times do |n|
name = "user#{n}"
email = "#{name}@example.com"
user = User.find_or_initialize_by(email: email, activated: true)
if user.new_record?
user.name = name
user.password = "password"
user.save!
end
end
puts "users = #{User.count}"
-
find_or_initialize_by
...ユーザーテーブルを
find_by(email: email, activated: true)
で検索する。- ユーザーが存在する場合 ... ユーザーオブジェクトを返す。
- 存在しない場合 ... 新しいユーザーオブジェクトを作成する。
-
if user.new_record?
... もしuser
が新規作成オブジェクトだった場合、 -
user.password = "password" ...
... パスワードをセットして保存。
これでSeedデータの準備が整いました。
ユーザーSeedデータを投入する
Railsは、
Seedデータを追加で投入したい時
$ rails db:seed
今あるSeedデータを全て削除して、新たに投入したい時
$ rails db:reset
今回はバリデーションでデモユーザーを作成したので、全てリセットして新たにユーザーを投入します。
reset
コマンドを実行しましょう。
root $ docker-compose run --rm api rails db:reset
...
users...
users = 10
Railsコンソールに入って確認してみましょう。
root $ docker-compose run --rm api rails c
> User.all
+----+-------+-------------------+-------------------------+-----------+-------+-------------------------+-------------------------+
| id | name | email | password_digest | activated | admin | created_at | updated_at |
+----+-------+-------------------+-------------------------+-----------+-------+-------------------------+-------------------------+
| 1 | user0 | user0@example.com | $2a$12$kljilHAWmLjYD... | true | false | 2020-07-14 11:09:03 ... | 2020-07-14 11:09:03 ... |
| 2 | user1 | user1@example.com | $2a$12$QMSnQWBXBuSUs... | true | false | 2020-07-14 11:09:04 ... | 2020-07-14 11:09:04 ... |
| 3 | user2 | user2@example.com | $2a$12$i1KuI4xNFCvks... | true | false | 2020-07-14 11:09:04 ... | 2020-07-14 11:09:04 ... |
...
10人のユーザーデータの確認が取れたら成功です。
コンソールから抜けましょう。
コミットしとく
これでユーザーSeedデータが用意できました。
ここまでの変更をコミットしておきましょう。
root $ cd api
api $ git add -A
api $ git commit -m "add_seed_data_users"
api $ cd ..
root $
まとめ
今回は環境ごとにSeedデータを切り替えるセッティングを行いました。
編集した
この回では、「test」「production」ディレクトリにseedファイルを作成しませんが、興味がある方は是非ファイルを作成しSeedデータを切り替えてみてください。
次回は?
ここまでにユーザーテーブル、Seedデータが整いましたが、まだバリデーションが正しく動いているかテストをしていませんね。
そこで次回はテスト環境を整えていきます。
どうぞ👇下へ。