db:create で ActiveRecord::NoDatabaseError factory_bot_rails の原因が factory_bot で モデル.new しているから？

# はじめに
製作中のアプリケーションにて、一度データベースを消して、再度作り成そうとしたところ、 `NoDatabaseError` が発生しました。
`rails db:create` を実行しているのに、 `NoDatabaseError`？ と思いましたが、エラーの内容を見る限り`factory_bot`に関係があることだけはわかります。


```zsh:console
username@pc article_app % rails db:drop
Dropped database 'article_app_development'
Dropped database 'article_app_test'

username@pc article_app % rails db:create
rails aborted!
ActiveRecord::NoDatabaseError: Unknown database 'article_app_development'
/Users/username/projects/article_app/spec/factories/article_tag.rb:2:in `block in <main>'
/Users/username/projects/article_app/spec/factories/article_tag.rb:1:in `<main>'
/Users/username/projects/article_app/config/environment.rb:5:in `<main>'
bin/rails:9:in `<main>'

Caused by:
Mysql2::Error: Unknown database 'article_app_development'
/Users/username/projects/article_app/spec/factories/article_tag.rb:2:in `block in <main>'
/Users/username/projects/article_app/spec/factories/article_tag.rb:1:in `<main>'
/Users/username/projects/article_app/config/environment.rb:5:in `<main>'
bin/rails:9:in `<main>'
Tasks: TOP => db:create => db:load_config => environment
(See full trace by running task with --trace)
```

# 結論
発生原因は **factory_bot 内で モデル.new している** からでした。
ダメなfactory_botの記述をしていたということです。
次のように記述していました。問題は2行目です。
`article = article.new` をコメントアウトすることで、エラーが出なくなります。

```ruby:(修正前)spec/factories/article_tag.rb
FactoryBot.define do
  article = article.new
  factory :article_tag do
    title       { Faker::Lorem.sentence }
    category_id { Faker::Number.within(range: 1..3) }
    tags        { Faker::Lorem.words.join(',') }
    content     do
      experience.content = '<div>asdf</div>'
      experience.content
    end
  end
end
```

```ruby:(修正後)spec/factories/article_tag.rb
FactoryBot.define do
  factory :article_tag do
    title       { Faker::Lorem.sentence }
    category_id { Faker::Number.within(range: 1..3) }
    tags        { Faker::Lorem.words.join(',') }
  end
end
```

```ruby:(修正後)spec/models/article_tag_spec.rb
require 'rails_helper'

RSpec.describe ArticleTag, type: :model do
  before do
    @article_tag = FactoryBot.build(:article_tag)
    @article_tag.content = '<div>rspec test data</div>'
```



# 理由
(英語ですら似た現象が出てこなかったので、自身は有りませんが、誰かしらの参考になればと思っています。)
次の内容は`rails db:create` コマンドを実行するときに、`--trace`を加えた場合の出力内容です。
この内容から、`rails db:create` コマンドは実行した後、まず設定ファイルや関連するGemも読み込んでいます。

```zsh:console
username@pc article_app % rails db:create --trace
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
rails aborted!
ActiveRecord::NoDatabaseError: Unknown database 'article_app_development'
...
...(長いので割愛)
...
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/attribute_methods.rb:171:in `has_attribute?'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/inheritance.rb:55:in `new'
/Users/username/projects/article_app/spec/factories/article_tag.rb:2:in `block in <main>'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/syntax/default.rb:37:in `instance_eval'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/syntax/default.rb:37:in `run'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/syntax/default.rb:7:in `define'
/Users/username/projects/article_app/spec/factories/article_tag.rb:1:in `<main>'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.9.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:60:in `load'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.9.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:60:in `load'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/find_definitions.rb:20:in `block (2 levels) in find_definitions'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/find_definitions.rb:19:in `each'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/find_definitions.rb:19:in `block in find_definitions'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/find_definitions.rb:15:in `each'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot-6.2.0/lib/factory_bot/find_definitions.rb:15:in `find_definitions'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/factory_bot_rails-6.2.0/lib/factory_bot_rails/railtie.rb:22:in `block in <class:Railtie>'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-6.0.4.1/lib/active_support/lazy_load_hooks.rb:68:in `block in execute_hook'
...
...(長いので割愛)
...
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.9.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.9.1/lib/bootsnap/
/Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootsnap-1.9.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
bin/rails:9:in `<main>'
Tasks: TOP => db:create => db:load_config => environment
```

その過程で`factory_bot_rails`が読み込まれています。
次のログから考えて、この`FactoryBot.find_definitions`で定義ファイルを読み込んで、ここまでが正常だと思います。
今回の問題が発生したのは次の`Reloader.new(app).run`だと思います。

```ruby:factory_bot_rails-6.2.0/lib/factory_bot_rails/railtie.rb
    config.after_initialize do |app|
      FactoryBot.find_definitions
      Reloader.new(app).run
    end
```

`Reloader.new(app).run`で呼び出されるのは、ログから考えると
factory_bot本体の`default.rb`の`define`が呼び出されています。
そして`new.instance_eval`で、factory_botの定義ファイルが実行されるようです。
その結果`active_record`が呼び出され、データベースを作っていないためエラーが発生しているようです。


```ruby:factory_bot-6.2.0/lib/factory_bot/syntax/default.rb
module FactoryBot
  module Syntax
    module Default
      include Methods
      def define(&block)
        DSL.run(block)
      end
...
      class DSL
...
        def self.run(block)
          new.instance_eval(&block)
        end
```


# 参考
[github: thoughtbot/factory_bot](https://github.com/thoughtbot/factory_bot)
[github: thoughtbot/factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails)
[rubyドキュメント: instance_eval](https://docs.ruby-lang.org/ja/latest/method/BasicObject/i/instance_eval.html)