Open4

エラー:bin/rails: no Ruby script found in input (LoadError)

iizkiizk

発生環境

- Ruby 3.4.3
- Ruby on Rails 7.2.2
- VS Code
- dev container extension

起きたこと

以下Railsチュートリアルの通り、
dev containerを使ってRailsアプリケーションを作成しようとした。

https://railsguides.jp/v7.2/getting_started_with_devcontainer.html

アプリケーションは作成されたが、rails -vを実行すると以下のエラーが出た。

bin/rails: no Ruby script found in input (LoadError)
vscode ➜ /workspaces/sample_project (main)

解決方法

.devcontainer/compose.yamlにポート設定を追加したら解決した

services:
  rails-app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    ports: # ポート設定の追加
      - "3000:3000"
iizkiizk

原因

まだちゃんと調べられてないけど、
Railsアプリケーションの bin/rails や bin/dev などのbinstubファイルが壊れていたり、空だったり、生成されていない場合、このエラーが発生するらしく、上記コマンドを実行しbinファイルを正しく生成し直すことで解消されるみたい。

ただ、bundler install --binstubsは2系以上だと非推奨なようなのであんまり使いたくない...

調査経緯

最初は

bundler install --binstubs

でもちゃんとrailsファイルが生成され直し無事解決はしたのですが、
--binstubsは2系から非推奨とのこと。

だったら推奨してる方法でいこう!と思い、

bundle binstubs rails

これで解決かと思いきや、

rails has no executables, but you may want one from a gem it depends on.
  bundler has: bundle, bundler
  railties has: rails

と言われる。

railsは実行可能なファイルを持ってないよ、でも依存先のこれらのgemなら持ってるかもー
とのこと。railsを持っているrailtiesで試してみる。

bundle binstubs railties

すると

Skipped rails since it already exists.
If you want to overwrite skipped stubs, use --force.

既存のファイルがあるとスキップしちゃうらしいので、
上書きしたいなら--forceオプションつけてね、とのこと。

じゃあこれでどう?

bundle binstubs railties --force

実行すると...

Beginning in Rails 4, Rails ships with a `rails` binstub at ./bin/rails that
should be used instead of the Bundler-generated `rails` binstub.

If you are seeing this message, your binstub at ./bin/rails was generated by
Bundler instead of Rails.

You might need to regenerate your `rails` binstub locally and add it to source
control:

 rails app:update:bin           # Bear in mind this generates other binstubs
                                # too that you may or may not want (like yarn)

If you already have Rails binstubs in source control, you might be
inadvertently overwriting them during deployment by using bundle install
with the --binstubs option.

If your application was created prior to Rails 4, here's how to upgrade:

  bundle config --delete bin    # Turn off Bundler's stub generator
  rails app:update:bin          # Use the new Rails executables
  git add bin                   # Add bin/ to source control

You may need to remove bin/ from your .gitignore as well.

When you install a gem whose executable you want to use in your app,
generate it and add it to source control:

  bundle binstubs some-gem-name
  git add bin/new-executable

/home/vscode/.rbenv/versions/3.4.3/lib/ruby/3.4.0/bundler/runtime.rb:317:in 'Bundler::Runtime#check_for_activated_spec!': You have already activated activesupport 8.0.2, but your Gemfile requires activesupport 7.2.2. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
        from /home/vscode/.rbenv/versions/3.4.3/lib/ruby/3.4.0/bundler/runtime.rb:25:in 'block in Bundler::Runtime#setup'
...

なるほど、bundlerは使わないで欲しいと...
これ以降についてはまた別日に調べる。

iizkiizk

余談ですが、Railsチュートリアルで出てくるrails-newツールを使ってアプリケーションを生成した際に、
rubyもrailsもバージョン指定をして実行したのですが、gemfileのrailsのバージョンだけ最新のものが指定されていたので、後から自分の使いたいバージョンを固定し直しました。