MySQL
Ridgepole
Rails5
DB設計

Rails5 + MySQL + Ridgepoleによる DB設計・開発(備忘録)

概要

  • Rails5 における MySQL + Ridgepole(Rails 用 DBスキーマ管理ツール)を用いたDB設計・開発

目次

  • 自身の環境
  • 必要なもの
  • プロジェクト作成
  • DB 作成(+ model 作成)
  • Ridgepole 適用
  • 開発フロー

自身の環境

  • OS : MaxOS High Sierra Version 10.13.6
  • MySQL : 5.7.18
  • Ruby : 2.5.0
  • Ruby on Rails : 5.2.0

必要なもの

プロジェクト作成

プロジェクト作成

$ rails new webapp -d mysql
$ cd webapp

gemfile の編集

 gemfile に ridgepole を追加しましょう。今回は、デフォルトの Gemfile に gem 'ridgepole'gem 'dotenv-rails' を入れただけにしました。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.0'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.0'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4', '< 0.6.0'

gem 'dotenv-rails'
gem 'ridgepole'  

# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15', '< 4.0'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  gem 'chromedriver-helper'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

 いつものやつを実行します。

$ ./bin/bundle install --path vendor/bundle

DB の設定

 それでは、 ./.env./config/database.yml を編集していきましょう。今回は、以下のような設定で、DB にアクセスしていきたいと思います。

(./.env)

DATABASE_USERNAME="webapp"
DATABASE_PASSWORD="webapp"
DATABASE_HOSTNAME="localhost"
(./config/database.yml)

default: &default
  adapter:  mysql2
  encoding: utf8
  pool:     5
  username: <%= ENV['DATABASE_USERNAME'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  host:     <%= ENV['DATABASE_HOSTNAME'] %>
  database: webapp

production:
  <<: *default

development:
  <<: *default

test:
  <<: *default
  database: webapp_test

DB 作成(+ model 作成)

ER図の作成

 次に実際に DB を作成していきます。はじめに、 MySQL Workbench を用いて、ER図を作成しましょう。

  • MySQL Workbench の起動

Screen Shot 2018-08-06 at 17.50.49.png

  • この画面から 左上の 「プラスボタン」をクリックします。

Screen Shot 2018-08-06 at 17.51.31.png

  • このような画面になると思うので、 真ん中上部の「Add Diagram」をクリックします。

  • 以下のような画面になったら、ER図作成が行えます。
     
    Screen Shot 2018-08-06 at 17.53.03.png

  • ごちゃごちゃして、以下のようになりました。ER図が作成された他(はたしてこれをER図というのかということはおいておいて.)に、画面右側の部分(これがDB名になります。)が 「mydb」から「webapp」になっていることに注意です。

Screen Shot 2018-08-06 at 17.56.59.png

  • このER図は、プロジェクト内に保存しておきましょう。今回は webapp/db/erd/webapp.mwb に保存しておきます。 File -> Save as Model から保存ができるはずです。

  • また、この Mysql Workbench は、 作成したER図のSQLをExport することができます。 File -> Export -> Forward Engineer SQL Script からやっていきましょう。作成された .sql ファイルを用いて、DBを作成していきます。 私は、 Sequel Pro というソフトを用いているので、このファイルをクリックすると以下のように自動的にSQL が実行できるようになります。

Screen Shot 2018-08-06 at 18.03.32.png

  • webapp DB と users テーブルができあがりました。(うわーい)

Screen Shot 2018-08-06 at 18.04.31.png

  • 次にこのDB にアクセスするユーザーを作成し、権限を付与していきます。以下のコマンドでいけるのかな。(Sequel Pro からいつもやってるので、あいまいです笑)
create user webapp identified by 'webapp';
grant all on webapp.* to 'webapp'@'%' identified by 'webapp';

model の作成

 users テーブルができたので user モデルを作成します。 webapp/models/user.rb ですかね。(今回は使わないですが…。)

class User < ApplicationRecord
  self.table_name = 'users'
end

Ridgepole 適用

 諸設定が終わりました。それでは、ridgepole を用いて、以下の2つをやっていきたいと思います。

  1. 既存の MySQL から スキーマファイルの作成
  2. スキーマファイル から MySQL に適用

rake タスクの作成

 以下のような webapp/lib/tasks/ridgepole.rake を作成します。この rake タスクを用いて、上記の2つをやっていきます。

namespace :ridgepole do
  task export: :environment do
    options = [
      '--export',
      '--split',
      "--output #{schemafile_path}"
    ]

    exec_ridgepole(options)
  end

  task apply: :environment do
    options = [
      '--apply',
      "--file #{schemafile_path}"
    ]

    exec_ridgepole(options)
  end

  def exec_ridgepole(options)
    yml_file_path = Rails.root.join('config', 'database.yml')
    default_options = [
      "--env #{Rails.env}",
      "--config #{yml_file_path}"
    ]

    sh("bundle exec ridgepole #{default_options.join(' ')} #{options.join(' ')}")
  end

  def schemafile_path
    Rails.root.join('db', 'schemas', 'Schemafile')
  end
end

rake タスクの実行

 以下のコマンドで、 現在の DB データをスキーマに落とし込みます。この場合 Schemafileusers.schema ファイルが作成されるはずです。

$ ./bin/bundle exec rake ridgepole:export

Screen Shot 2018-08-06 at 18.18.02.png

  また以下のコマンドで、既存のスキーマファイルを DB に反映させます。今回は、特にDB に変更はないですね。

$ ./bin/bundle exec rake ridgepole:apply

Screen Shot 2018-08-06 at 18.20.03.png

開発フロー

 まとめると開発フローとしては、以下のようになるかなーと考えています。初期設定が終わっていることを前提としています。

  1. DB に変更がでちゃったよ〜。 >< >< >< ><
  2. ER図編集するよ。
  3. MySQL に反映するよ。
  4. $ ./bin/rake ridgepole:export して、スキーマファイル作成するよ。
  5. みんなにあげるよ。 $ ./bin/rake ridgepole:apply してね。