Sinatraのdatabase.ymlでdotenvを使いたい
こんちか!! たくみんです。最近はSinatraを使って、ちょっとしたWebアプリを作っています。その際にハマったポイントがあるので、備忘録として記事を書いています。
開発中のアプリケーションの構成は、以下のような感じです。
- rbenv : 1.1.1-39-g59785f6
- ruby : 2.6.0
- sinarra : 2.0.5
- mysql : Ver 8.0.13 for osx10.14 on x86_64 (Homebrew)
./ ├── app.rb ├── config.ru ├── database.yml ├── Gemfile └── Gemfile.lock
ハマったポイント
今回開発中のアプリケーションでは、databaseに接続するための情報を、database.yml
に記述することにしました。
しかしながら、ユーザネームやパスワードなどの情報を、GitHubのpublicリポジトリにpushするのは、あまりよくありません。
そこで、.env
とgem dotenv
による管理を行うことにしました。
Railsのdatabase.ymlには、erb記法が利用できるという記事を発見したので、Sinatraでも行けるでしょと思い、やってみることにしました。
そのときのdatabase.ymlとSinarraのapp.rbは以下のような感じです。
adapter: mysql2 encoding: utf8 reconnect: false database: sqlapps pool: 5 username: <%= ENV["MYSQL_USERNAME"] %> password: <%= ENV["MYSQL_PASSWORD"] %> host: localhost
require 'sinatra' require 'sinatra/reloader' require 'mysql2' require 'dotenv' require 'yaml' set :bind, '0.0.0.0' Dotenv.load sql_client = Mysql2::Client.new(YAML.load_file('./database.yml')) get '/' do # 省略 end
Sinatraを起動してみると、以下のように、erb記法がうまく解釈されておらず、接続ができていないことがわかります。
Access denied for user '<%= ENV["MYSQL_USERNAME"] %>'@'localhost' (using password: YES) (Mysql2::Error::ConnectionError)
解決方法
解決方法が以下の記事に乗っていました。
この記事によると、以下の手順を踏むことで、解決できるようです。
- File.readで
database.yml
を読み込む - ERB.new()の引数に、1.を与える
- 2.の結果をresult methodで取り出し、yamlとして読み込ませる
- 3.の結果をmysql2の引数として与える
コードにすると以下のような感じです。
Mysql2::Client.new(YAML.load(ERB.new(File.read("./database.yml")).result))
修正結果
解決方法を踏まえて、Sinatraのapp.rbを以下のように修正しました。
require 'sinatra/base' require 'sinatra/reloader' require 'mysql2' require 'dotenv' require 'yaml' require 'erb' class SQLApplication < Sinatra::Base Dotenv.load yaml_file = File.read("./database.yml") sql_client = Mysql2::Client.new(YAML.load(ERB.new(yaml_file).result)) get '/' do query = "select * from test1" output = "" result = sql_client.query(query) result.each do |a| output = a["text"] end return output end end
疎通確認として、適当なテーブルを作成し、表示させてみます。 テーブルは以下のような感じです。
test1 +---------------+-------------+ | id(integer) | text (text) | +---------------+-------------+ | 1 | test | +---------------+-------------+
表示結果が下の画像です。
成功です。うまくQueryの結果を表示していることがわかります。
終わりに
Railsだと、コマンド叩いてけばdatabase.ymlが勝手に作られ、 dotenv-railsのおかげで、勝手にerbを解釈してくれるので、楽なのですが、 Sinatraだと全部自分でやらないといけないので、勉強になりました。
やっぱりRailsってすごい…