LoginSignup
7
4

More than 1 year has passed since last update.

Rails6 のちょい足しな新機能を試す82(db:seed:replant 編)

Last updated at Posted at 2019-09-20

はじめに

Rails 6 に追加されそうな新機能を試す第82段。 今回は、 db:seed:replant 編です。
Rails 6 では、 データをすべて削除する db:truncate_all , 全部データを削除してから、 seed データを投入する db:seed:replant の2つのタスクが追加されました。
マルチデータベースにも対応しています。

Ruby 2.6.4, Rails 6.0.0, PostgreSQL 10.7, MySQL 8.0.17 で確認しました。

$ rails --version
Rails 6.0.0

今回は、 マルチデータベースを使います。 Backbone データベースは、 PostgreSQLを Library データベースは、 MySQL を使います。
Backbone に User テーブルを作ります。
Library に Book テーブルを作ります。

User と Book の seed データを作成し、タスクを実行して動作を確認します。

プロジェクトを作る

rails new rails_sandbox
cd rails_sandbox

Gemfile に pg と mysql2 を追加する

PostgreSQL と MySQL の両方のデータベースを扱うので、 pgmysql2 gem をGemfile に追加します。

...
# Use mysql as the library database for Active Record
gem 'mysql2', '>= 0.4.4'
# Use postgresql as the backbone database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
...

bundle install します。

$ bundle install

config/database.yml を編集する

config/database.yml を編集して、 backbone と library の2つの接続情報を設定します。
データベースサーバの host名は、わかりやすいように postgres と mysql にしました。

config/database.yml
default_postgresql: &default_postgresql
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: postgres
  user: <%= ENV.fetch("POSTGRES_USER") %>
  password: <%= ENV.fetch("POSTGRES_PASSWORD") %>

default_mysql: &default_mysql
  adapter: mysql2
  encoding: utf8mb4
  username: root
  password:
  host: mysql

development:
  backbone:
    <<: *default_postgresql
    database: backbone_development
  library:
    <<: *default_mysql
    database: library_development
    migrations_paths: db/library_migrate
  ...

User モデルを作る

name の属性をもつ User モデルを作ります。

bin/rails g model User name

Book モデルを作る

title 属性をもつ Book モデルを作ります。
このとき --db オプションで library を指定します。

bin/rails g model Book title -db library

Book モデルを編集する

connects_to を使って、Book モデルの接続先を library 側に変更します。

app/models/book.rb
class Book < ApplicationRecord
  connects_to database: { writing: :library, reading: :library }
end

seed データを作る

users と books の2つの seed データを作ります。

db/seeds.rb
User.create(
  [
    { name: 'Taro' },
    { name: 'Hanako' }
  ]
)

Book.create(
  [
    { title: 'Programming Ruby' },
    { title: 'Agile Web Development with Rails' }
  ]
)

マイグレーションを実行し seed データを登録する

bin/rails db:create db:migrate db:seed

rails console で確認する

rails console で User と Book の件数を調べてみます。

irb(main):001:0> User.count
   (0.5ms)  SELECT COUNT(*) FROM "users"
=> 2
irb(main):002:0> Book.count
   (0.2ms)  SET NAMES utf8mb4,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
   (6.3ms)  SELECT COUNT(*) FROM `books`
=> 2

psql と mysql で確認する

psql で users テーブルのデータを確認します。

backbone_development=# select * from users;
 id |  name  |         created_at         |         updated_at
----+--------+----------------------------+----------------------------
  1 | Taro   | 2019-09-06 22:45:38.356429 | 2019-09-06 22:45:38.356429
  2 | Hanako | 2019-09-06 22:45:38.361014 | 2019-09-06 22:45:38.361014
(2 rows)

mysql で books テーブルのデータを確認します。

mysql> select * from books;
+----+----------------------------------+----------------------------+----------------------------+
| id | title                            | created_at                 | updated_at                 |
+----+----------------------------------+----------------------------+----------------------------+
|  1 | Programming Ruby                 | 2019-09-06 22:45:38.378629 | 2019-09-06 22:45:38.378629 |
|  2 | Agile Web Development with Rails | 2019-09-06 22:45:38.395576 | 2019-09-06 22:45:38.395576 |
+----+----------------------------------+----------------------------+----------------------------+
2 rows in set (0.00 sec)

もう一度 db:seed を実行する

ここで、もう一度 db:seed を実行します。

$ bin/rails db:seed

User と Book の件数は増えます。

irb(main):003:0> User.count
   (0.8ms)  SELECT COUNT(*) FROM "users"
=> 4
irb(main):004:0> Book.count
   (3.1ms)  SELECT COUNT(*) FROM `books`
=> 4

psql と mysql で確認しても同様に件数が増えています。

psql:

backbone_development=# select * from users;
 id |  name  |         created_at         |         updated_at
----+--------+----------------------------+----------------------------
  1 | Taro   | 2019-09-06 22:45:38.356429 | 2019-09-06 22:45:38.356429
  2 | Hanako | 2019-09-06 22:45:38.361014 | 2019-09-06 22:45:38.361014
  3 | Taro   | 2019-09-06 22:58:19.359173 | 2019-09-06 22:58:19.359173
  4 | Hanako | 2019-09-06 22:58:19.365323 | 2019-09-06 22:58:19.365323
(4 rows)

mysql:

mysql> select * from books;
+----+----------------------------------+----------------------------+----------------------------+
| id | title                            | created_at                 | updated_at                 |
+----+----------------------------------+----------------------------+----------------------------+
|  1 | Programming Ruby                 | 2019-09-06 22:45:38.378629 | 2019-09-06 22:45:38.378629 |
|  2 | Agile Web Development with Rails | 2019-09-06 22:45:38.395576 | 2019-09-06 22:45:38.395576 |
|  3 | Programming Ruby                 | 2019-09-06 22:58:19.382802 | 2019-09-06 22:58:19.382802 |
|  4 | Agile Web Development with Rails | 2019-09-06 22:58:19.397899 | 2019-09-06 22:58:19.397899 |
+----+----------------------------------+----------------------------+----------------------------+
4 rows in set (0.00 sec)

db:seed:replant を試す

db:seed:replant を試してみましょう。

$ bin/rails db:seed:replant

rails console で確認するとデータは増えずに2件ずつとなっています。

irb(main):005:0> User.count
   (1.0ms)  SELECT COUNT(*) FROM "users"
=> 2
irb(main):006:0> Book.count
   (5.0ms)  SELECT COUNT(*) FROM `books`
=> 2

psql と mysql でも確認します。

psql:

backbone_development=# select * from users;
 id |  name  |         created_at         |         updated_at
----+--------+----------------------------+----------------------------
  5 | Taro   | 2019-09-06 23:05:17.516149 | 2019-09-06 23:05:17.516149
  6 | Hanako | 2019-09-06 23:05:17.524706 | 2019-09-06 23:05:17.524706
(2 rows)

mysql:

mysql> select * from books;
+----+----------------------------------+----------------------------+----------------------------+
| id | title                            | created_at                 | updated_at                 |
+----+----------------------------------+----------------------------+----------------------------+
|  1 | Programming Ruby                 | 2019-09-06 23:05:17.573838 | 2019-09-06 23:05:17.573838 |
|  2 | Agile Web Development with Rails | 2019-09-06 23:05:17.585832 | 2019-09-06 23:05:17.585832 |
+----+----------------------------------+----------------------------+----------------------------+
2 rows in set (0.00 sec)

db:truncate_all を実行する

最後に db:truncate_all を実行してみます。

$ bin/rails db:truncate_all

rails console で確認すると、データが削除されていることがわかります。

irb(main):007:0> User.count
   (1.1ms)  SELECT COUNT(*) FROM "users"
=> 0
irb(main):008:0> Book.count
   (2.4ms)  SELECT COUNT(*) FROM `books`
=> 0

sqlite3

sqlite3 には、 truncate が存在しないため、代わりに、 DELETE FROM (テーブル名) を使っています。

試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try082_db_seed_replant

参考情報

7
4
1

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
7
4