LoginSignup
1
1

More than 1 year has passed since last update.

rails db:system:changeコマンドはSpring経由で実行するとinvalid optionで失敗する

Last updated at Posted at 2022-05-30

はじめに

rails db:system:changeコマンドはRails6で追加されたコマンドです。
このコマンドにより、Railsが使用するDBをPostgreSQLやMySQL等に簡単に変更できるはずなのですが、試しに実行してみたところ、以下のようなエラーになりました。

% rails db:system:change --to=postgresql
Running via Spring preloader in process 15906
invalid option: --to=postgresql

調査したところ、回避方法や原因がわかったので以下に説明します。

回避方法

Springを無効にすることで回避できます。
SpringはRails6の場合、development環境において標準で有効になっています。
Springにはrailsやrakeコマンドの実行時間を短縮する効果がありますが、マシンスペックの向上に対してその恩恵が少なくなったと判断され、Rails7では標準で無効となりました。
したがって、多くの場合無効にしても問題にならないと思います。

簡単にSpringを無効にする方法は以下です。

1: Gemfileでspringをコメントアウトします。

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  # gem 'spring' # ← ここ
end

2: bundle installを実行します。

rails db:system:changeコマンドの実行後、再度Springを使いたい場合は、コメントアウトを戻してbundle installすれば使えます。

原因

GitHubのissueで報告したのですが、直接的な原因はSpringのこの修正です。
全てのdbコマンドに対してrakeが呼び出されるようになっていました。
したがって、以下のコマンドのエラーが表示されていたということになります。

% rake db:system:change --to=postgresql
invalid option: --to=postgresql

db:system:changeは他と違ってrake taskではないためエラーになります。

なお、問題の修正が入ったのはspring gemのv3.1.1からなので、v3.1.0までなら本現象は発生しません。

今後の対処

Spring側を修正する方針になったので、PRを出しておきました。
したがって、今後Spring gemが更新されると修正される見込みです。

ちなみに、この修正にはもう1個問題があって、railsコマンドを引数なしで実行すると以下のようにNoMethodErrorで失敗します。

% rails
Traceback (most recent call last):
	12: from bin/rails:2:in `<main>'
	11: from bin/rails:2:in `load'
	10: from /Users/inayuky/work/rails-postgre/bin/spring:7:in `<top (required)>'
	 9: from /Users/inayuky/work/rails-postgre/bin/spring:7:in `tap'
	 8: from /Users/inayuky/work/rails-postgre/bin/spring:10:in `block in <top (required)>'
	 7: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
	 6: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
	 5: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/binstub.rb:11:in `<top (required)>'
	 4: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/binstub.rb:11:in `load'
	 3: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/bin/spring:49:in `<top (required)>'
	 2: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/client.rb:30:in `run'
	 1: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/client/command.rb:7:in `call'
/Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/client/rails.rb:25:in `call': undefined method `start_with?' for nil:NilClass (NoMethodError)

これもSpringを無効にすることで回避できます。
こちらはこの修正により、将来直るはずです。

なお、Rails7だと標準ではSpringが無効になっていますが、Springを有効にするとRails7でもこれらの現象は発生します。

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1