railsでポートフォリオするにあたって、DBの構築にMySQL2を使おうと思いましたが、何回もエラーが出たので解決までの過程を書いていきます。
開発環境
Mac OS Catalina: 10.15.7
メモリ: 8G
ruby:2.6.6
rails: 6.1.1
#実現したいこと
rails db:create 実行時にMySQL2でデータベースを構築したい
#homebrewでmysqlをインストール
ターミナルで以下のコマンドを実行
brew install mysql
しかし、エラー発生。エラー文には以下の様に書かれていた。
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
このエラーは以下の記事と全く同じ手順で解決した。
rails db:create を実行するがDBがsqlite3で構築されてしまう
rails db:create を実行すると以下の様に表示された
Database 'db/development.sqlite3' already exists
Database 'db/test.sqlite3' already exists
色々調べた結果、config/database.ymlファイルの設定がおかしい様だ。
# SQLite. Versions 3.8.0 and up are supported.
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
#
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: db/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: db/test.sqlite3
production:
<<: *default
database: db/production.sqlite3
config/database.yml の中はdefalt設定とdevelopment設定とproduction設定が存在する。
このうち、defaultのadapterで接続するデータベース構築支援システムを指定している。
これをmysql2に変更する。
default: &default
adapter: mysql2
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
再び rails db:create を実行するが、以下の様なエラーが発生した。
rails aborted!
LoadError: Error loading the 'mysql2' Active Record adapter. Missing a gem it depends on? mysql2 is not part of the bundle. Add it to your Gemfile.
/Users/cha-han/workspace/room-anatomy/bin/rails:5:in `<top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:10:in `block in <top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `tap'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `<top (required)>'
Caused by:
Gem::LoadError: mysql2 is not part of the bundle. Add it to your Gemfile.
/Users/cha-han/workspace/room-anatomy/bin/rails:5:in `<top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:10:in `block in <top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `tap'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `<top (required)>'
Tasks: TOP => db:create => db:load_config
(See full trace by running task with --trace)
エラー文前半をみるとMySQL2のgemがbundleの中にないからMySQL2のgemをGemfileに追加しろ、と書いてある。
Gemfileの中に
gem 'sqlite3', '~> 1.4'
と書いてあったので、これを
gem 'mysql2', '~> 0.5.3'
に変更して再びrails db:createを実行した。
再びエラー発生。
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.`sqlite3` DEFAULT CHARACTER SET `utf8mb4`' at line 1
Couldn't create 'db/development.sqlite3' database. Please check your configuration.
rails aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.`sqlite3` DEFAULT CHARACTER SET `utf8mb4`' at line 1
/Users/cha-han/workspace/room-anatomy/bin/rails:5:in `<top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:10:in `block in <top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `tap'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `<top (required)>'
Caused by:
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.`sqlite3` DEFAULT CHARACTER SET `utf8mb4`' at line 1
/Users/cha-han/workspace/room-anatomy/bin/rails:5:in `<top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:10:in `block in <top (required)>'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `tap'
/Users/cha-han/workspace/room-anatomy/bin/spring:7:in `<top (required)>'
Tasks: TOP => db:create
(See full trace by running task with --trace)
SQL構文がおかしいからそれを修正してくれと言っている様だ。おそらくconfig/database.ymlの中身がsqlite3の設定のままだからそれをmysql2用にすればいいはず。
そしてググっていると、この時点でようやくrails new アプリケーション名 -d mysql
としてアプリ開発を始めていれば勝手にmysql2で開発がスタートしていたことが判明。
rails new アプリケーション名 -d mysql
で新たにアプリを作成し、そのアプリのconfig/database.ymlの中身をそのままコピーして、修正中のアプリのconfig/database.ymlに貼り付けた。
以下にそのconfig/database.ymlの中身を書いておく。database名とusernameは貼り付けた後に自分で指定した。
# MySQL. Versions 5.5.8 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password:
socket: /tmp/mysql.sock
development:
<<: *default
database: room_anatomy2_development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: room_anatomy2_test
# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password or a full connection URL as an environment
# variable when you boot the app. For example:
#
# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# If the connection URL is provided in the special DATABASE_URL environment
# variable, Rails will automatically merge its configuration values on top of
# the values provided in this file. Alternatively, you can specify a connection
# URL environment variable explicitly:
#
# production:
# url: <%= ENV['MY_APP_DATABASE_URL'] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#
production:
<<: *default
database: room_anatomy2_production
username: room_anatomy2
password: <%= ENV['ROOM_ANATOMY2_DATABASE_PASSWORD'] %>
rails db:create
を実行するとmysql2でDBを構築することができた。
まとめ
・DBの設定はconfig/database.ymlで設定
・使用するmysqlはGemfileで指定する
アプリ作成時に使用するDB名を指定しておけば上記の様な面倒なことは起こりませんでしたが、色々知識が増えたので結果オーライ、と前向きに考えておきますw