👻

herokuにデプロイしたら「Stringクラスにpresent?メソッドはないよ」?

2021/01/17に公開

発生した問題

git push heroku masterしたらbin/bundleでNoMethodError。
google先生にたずねてみたが、出てくる記事は「commit忘れ」「sqlitじゃなくてポスグレ入れろ」の二種類ばかり。
NoMethodError記事もあるにはあるが「Nilclassにto_symはないよ」がほとんど。
探しに探してようやく見つけたのがこれ。
https://teratail.com/questions/308389#reply-434607

本件解決いたしました!
bin/bundleファイルにエラーが発生していた様なので修正したところ無事デプロイすることができました。

どうやって修正するのか書いてくれぇい……。
もう手打ちで修正してくれようか、と考えていてふと気づく。
そもそもエラーが起きているってbinディレクトリのbinって何なんだ?

binディレクトリの中身はbinstub

gemのバイナリファイルやシェルスクリプトはいきなり動かす事はできず、環境を整えてやる必要がある。
その環境構築に使われるのがbinstubファイル。
普通はgemをインストールした時にrubygemsが生成する……らしい。
このbinstubというワードを検索窓に打ち込むと、google先生が「何や、最初からそう言えや」とばかりに一発で正解に連れて行ってくれた。

binstubの更新方法

https://qiita.com/tanaka51/items/bc22c1c364202d3cce4e#bundler-が生成する-binstub

今回エラーが出ているのはbin/bundleの42行目。

bin/bundle
    return gemfile if gemfile.present?

ここでgemfileにStringクラスが入っているせいでエラーが出ている。「いや存在するはずだろ、何ならプライベートメソッドとしてもう一回書いたろか」と思わなかったのが不幸中の幸い。present?でググれば、これがrubyに組み込まれていないactivesupportオンリーのメソッドだと出てくる。ここがruby組み込みのnil?かempty?になればいいはずだ。
qiitaの記事に従い、bundle binstubs bundler -fでbin/bundleを上書きする。

bin/bundle
    return gemfile if gemfile && !gemfile.empty?

はいOK。
この後yarnで入れたはずのポスグレが何故か消えていたり、gemでポスグレ入れたらyarnのポスグレと競合したりするのだがそれは別の話。

Discussion