ridgepole [ERROR] uninitialized constant Rails (erb):16:in `<main>'

忘備録
自分用とはいえだいぶ読みにくいと思います。すみません。


## 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
した時。

```cmd

[ERROR] uninitialized constant Rails
        (erb):16:in `<main>'
```

**？？？？ どこの何がどうエラーなん!?!?**
と困惑。エラーメッセージは「uninitialized constant Rails　(erb):16:in `<main>'」
だけでNameErrorとかも何も教えてくれなかったので。


調べた感じ、とりあえず初期化時にクラスやファイルの読み込みが上手く行ってなかったりなんだな～
と思ったので、前に上手く行った段階と今回でファイルをいじったなって所をコメントアウトやら色々試していった。

＋元々こちらの記事を読んだことがあったので→  [ridgepole 導入はまりどころ](https://qiita.com/ToqTock/items/c185a38fd4e2011ddd64)
自分で試しているうちに
「そういえばdatabase.ymlもいじって、

```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行目でエラー出てたけど、まさにこの場所でした。

試しに

```database.yml
username: testuser
password: testpass1111
```
と展開なしで直接書いたらバッチリ動きました。

### ついでにdotenvを使うことにした

dotenv自体の使い方については
[Railsで使える環境変数を管理できるgem(dotenv-rails)や.envの導入方法](https://qiita.com/ryosuketter/items/ceb592dc6b23a20e51b5)
を参考にしつつ。

ついでに気になったので下記の記事も読みました。
[ENV[]とENV.fetch()の違い【Rails/Ruby】](https://qiita.com/sukebeeeeei/items/576f109d57218c8397d5)
gitにdatabase.ymlはあげて管理したいので、fetchの方を使ってデフォルト値も入力してしまうと
結局見えちゃって意味ないな～と思い
出力するときはENV.fetchじゃなく普通にENV['']使いました。

```
development:
  <<: *default
  database: skuemy_system_development
  username: <%= ENV['DATABASE_USERNAME'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
```

として読み込むようにしました。

## しかし
ymlファイルのコメントアウトがどうも上手く働いてくれないままなんですが。
上記のように変えて、
下の方に

```database.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
とかしても

```cmd
[ERROR] uninitialized constant Rails
        (erb):57:in `<main>'
```

ってさっきコメントアウトしていた行、57行目でダメーって言われました。
なのでメモは別でとっておくとして、消しました。そうすると無事に動......

### きません。
```
[ERROR] Access denied for user 'ユーザー名'@'localhost' (using password: NO)
```
とでます。つまるところデータベースへのアクセス。usernameとpasswordが間違ってるか無いよって言われます。
dotenvで展開してるのにナンデ!?なのですが。
下記の記事を読んでいたので。(2回目)
[ridgepole 導入はまりどころ ==> 案3　コマンド実行時に即時展開](https://qiita.com/ToqTock/items/c185a38fd4e2011ddd64#%E6%A1%883%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C%E6%99%82%E3%81%AB%E5%8D%B3%E6%99%82%E5%B1%95%E9%96%8B)

案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内から間接的に」
も動きました。実際に使っているコード一応貼っておきます。
ファイル名は適当です。
編集したのはファイルの参照部分だけです。

```task_ridgepole_apply.rake
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タスク内でリスクを担保する](https://qiita.com/EastResident/items/c53c1e69d677f85a4d72#rake%E3%82%BF%E3%82%B9%E3%82%AF%E5%86%85%E3%81%A7%E3%83%AA%E3%82%B9%E3%82%AF%E3%82%92%E6%8B%85%E4%BF%9D%E3%81%99%E3%82%8B)
感謝です。ほんとに。


<br>
## まとめ（れてない）
ymlの一部コメントアウトが効かないのは今の所1mmも意味が分かりませんが、
そのコメント部分を消して。
「bundle exec dotenv -f ".env" ridgepole -c config/database.yml -E development -f db/Schemafile --apply --dry-run」
(dry-runを付ける場合の話)
で動いているのでヨシとします。(現場猫)
<br>
余談ですが、

```database.yml
#  username: <%= ENV['DATABASE_USERNAME'] %>
#  password: <%= ENV['DATABASE_PASSWORD'] %>
```
と、dotenvで展開していた方をコメントアウトしたらちゃんと（passとかが無いよって）エラーでてくれたので。
そっちはコメントアウト効いているようです。
もうよくわかりません。
Rails.application.credentialsに何かあるとしか......。