忘備録
自分用とはいえだいぶ読みにくいと思います。すみません。
intro
いつものように開発環境コマンドプロンプトにて。
bundle exec ridgepole --config ./config/database.yml --file ./db/Schemafile --apply --dry-run
もしくは
bundle exec ridgepole --config ./config/database.yml --file ./db/Schemafile --apply
した時。
[ERROR] uninitialized constant Rails
(erb):16:in `<main>'
???? どこの何がどうエラーなん!?!?
と困惑。エラーメッセージは「uninitialized constant Rails (erb):16:in `'」
だけでNameErrorとかも何も教えてくれなかったので。
調べた感じ、とりあえず初期化時にクラスやファイルの読み込みが上手く行ってなかったりなんだな~
と思ったので、前に上手く行った段階と今回でファイルをいじったなって所をコメントアウトやら色々試していった。
+元々こちらの記事を読んだことがあったので→ ridgepole 導入はまりどころ
自分で試しているうちに
「そういえばdatabase.ymlもいじって、
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= Rails.application.credentials.mysql[:username] %> 👈ココ
password: <%= Rails.application.credentials.mysql[:password] %> 👈ココ
host: localhost
とかで展開してたな......」と。
dotenvじゃないですが、開発環境でcredentials使っているので(本来は本番環境だけで使うもの)
これだなと、--apply時にうまく展開されてないんだなと。
16行目でエラー出てたけど、まさにこの場所でした。
試しに
username: testuser
password: testpass1111
と展開なしで直接書いたらバッチリ動きました。
ついでにdotenvを使うことにした
dotenv自体の使い方については
Railsで使える環境変数を管理できるgem(dotenv-rails)や.envの導入方法
を参考にしつつ。
ついでに気になったので下記の記事も読みました。
ENV[]とENV.fetch()の違い【Rails/Ruby】
gitにdatabase.ymlはあげて管理したいので、fetchの方を使ってデフォルト値も入力してしまうと
結局見えちゃって意味ないな~と思い
出力するときはENV.fetchじゃなく普通にENV['']使いました。
development:
<<: *default
database: skuemy_system_development
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
として読み込むようにしました。
しかし
ymlファイルのコメントアウトがどうも上手く働いてくれないままなんですが。
上記のように変えて、
下の方に
# username: <%= Rails.application.credentials.mysql[:username] %>
# password: <%= Rails.application.credentials.mysql[:password] %>
と下の方にメモ書きとして残しておいたのです。ですが、
コメントアウトしているにもかかわらず読み込もうとするんです。(未解決)
なので
bundle exec ridgepole --config ./config/database.yml --file ./db/Schemafile --apply --dry-run
とかしても
[ERROR] uninitialized constant Rails
(erb):57:in `<main>'
ってさっきコメントアウトしていた行、57行目でダメーって言われました。
なのでメモは別でとっておくとして、消しました。そうすると無事に動......
きません。
[ERROR] Access denied for user 'ユーザー名'@'localhost' (using password: NO)
とでます。つまるところデータベースへのアクセス。usernameとpasswordが間違ってるか無いよって言われます。
dotenvで展開してるのにナンデ!?なのですが。
下記の記事を読んでいたので。(2回目)
ridgepole 導入はまりどころ ==> 案3 コマンド実行時に即時展開
案3にあるコマンド実行時に即時展開というのを少し編集して使うことにします。
bundle exec dotenv -f ".env" ridgepole -c config/database.yml -E development -f db/Schemafile --apply --dry-run
ファイルの場所は任意なので変えるのは当然として
splitしたくなかったり、
そもそもファイルは既に作ってあるので--export とか--outputは使いませんでした。
「案4 rake task内から間接的に」
も動きました。実際に使っているコード一応貼っておきます。
ファイル名は適当です。
編集したのはファイルの参照部分だけです。
namespace :db do
desc 'apply Schemafile and update schema.rb'
task apply: :environment do
ENV['ALLOW_DROP_TABLE'] ||= '0'
ENV['ALLOW_REMOVE_COLUMN'] ||= '0'
ENV['RAILS_ENV'] ||= 'development'
task_return = `ridgepole -E #{ENV['RAILS_ENV']} --diff config/database.yml db/Schemafile`
column_condition = task_return.include?('remove_column') && ENV['ALLOW_REMOVE_COLUMN'] == '0'
table_condition = task_return.include?('drop_table') && ENV['ALLOW_DROP_TABLE'] == '0'
if column_condition || table_condition
puts '[Warning]this task contains some risks: "remove_column" or "drop_table"'
else
sh "ridgepole -E #{ENV['RAILS_ENV']} -c config/database.yml --apply -f db/Schemafile"
sh 'rake db:schema:dump'
end
end
end
これで誤ってテーブルが削除されたりするリスクがだいぶ減りそうです。
Rakeタスク内でリスクを担保する
感謝です。ほんとに。
## まとめ(れてない) ymlの一部コメントアウトが効かないのは今の所1mmも意味が分かりませんが、 そのコメント部分を消して。 「bundle exec dotenv -f ".env" ridgepole -c config/database.yml -E development -f db/Schemafile --apply --dry-run」 (dry-runを付ける場合の話) で動いているのでヨシとします。(現場猫)
余談ですが、
# username: <%= ENV['DATABASE_USERNAME'] %>
# password: <%= ENV['DATABASE_PASSWORD'] %>
と、dotenvで展開していた方をコメントアウトしたらちゃんと(passとかが無いよって)エラーでてくれたので。
そっちはコメントアウト効いているようです。
もうよくわかりません。
Rails.application.credentialsに何かあるとしか......。