uot
@uot (uo yu)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Rails】「To install the missing version, run `gem install bundler:2.1.4`」のエラーを解決したいです。

前提・実現したいこと

railsにて,
Wheneverを使ってRakeタスクを定期実行をしようと思っています。
その際に、logを確認しますと下記のようなエラーが発生します。
2日以上こちらが解決しない状態です。。。

発生している問題・エラーメッセージ

To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.1.4`

試したこと

gem install bundler:2.1.4が反映されていないと思い
こちらの記事を参照に
(1) Gemfile.lockを削除

$ rm Gemfile.lock

(2) バージョン2.1.4のbundlerをインストール

$ gem install bundler -v 2.1.4

(3) (2)のbundlerを用いて再度gemを入れ直す

$ bundler _2.1.4_ install

0

11Answer

すみません、 runner から rake に変わったのを見落としていました。 以下のように rake 用の設定も足してください。

set :path_env, ENV['PATH']
job_type :runner, "cd :path && PATH=':path_env' bin/rails runner -e :environment ':task' :output"
job_type :rake,   "cd :path && PATH=':path_env' :environment_variable=:environment bundle exec rake :task --silent :output"
1Like

@github0013@github gem install bundler:2.1.4gem install bundler -v 2.1.4 は同じ意味です。そのエラーメッセージの通りにしても解決していないということです。(bundle update --bundler は試していないようですが、これは Gemfile.lock に現在の Bundler のバージョンを書き込むだけなのでここでは無意味です)


@uot Whenever は cron を使ってタスクを実行しますが、 cron には .bashrc などで設定された PATH 環境変数が反映されません。そのせいで、普段使っている Ruby と cron で起動する Ruby が異なる可能性が考えれられます。

Whenever で ruby --versionbundler --version や ruby -e 'p ENV["PATH"]' コマンドを実行してバージョンと PATH を確認してみてください。

この問題に該当する場合、解決策は以下のどちらかです。

  • cron で起動する Ruby に対して Bundler 2.1.4 をインストールする
  • cron で普段の Ruby を起動する

普段の Ruby を起動するなら、 config/schedule.rb に env 'PATH', ENV['PATH'] と書いてください。これで bundle exec whenever を実行した時点での PATH を crontab (cron のタスク定義ファイル)に書き込むことができます。

0Like

@usai 
ご返信ありがとうございます!

上記のとおりに確認と実行してみました、こちらで合ってますでしょうか??

【確認作業】
・ruby --versionでバージョン確認

ターミナル

ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin20]

・bundler --version

ターミナル
Bundler version 2.1.4

・ruby -e 'p ENV["PATH"]'

"/Users/uot/.rbenv/versions/2.6.5/bin:/usr/local/Cellar/rbenv/1.1.2/libexec:/opt/homebrew/bin:/usr/local/opt/node@14/bin:/usr/local/opt/mysql@5.6/bin:/Users/uot/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:/usr/local/opt/node@14/bin:/usr/local/opt/mysql@5.6/bin:/Users/uot/.rbenv/shims"

バージョンがずれているので、、
【行った作業】
・cron で普段の Ruby を起動する
config/schedule.rb

require File.expand_path(File.dirname(__FILE__) + '/environment')
env 'PATH', ENV['PATH']
rails_env = ENV['RAILS_ENV'] || :development
set :output, "#{Rails.root}/log/cron.log"
set :environment, rails_env

every 1.minutes do
  runner  "ThanxMailer.a.deliver_now" 
end

再度同じエラーが出てしまいました。。。
理解不足で申し訳ございませんが、なにか間違っておりましたら、ご指摘頂きたいです。

/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.1.4) required by your /Users/uot/projects/subscription/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.1.4`
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
    from /usr/bin/bundle:23:in `<main>'
 ```
0Like

確認作業はターミナルで ruby --version などと実行されたように見えます。それだと普段の Ruby のバージョンなどが出てしまって意味がありません。 Whenever のタスクに command 'ruby --version' などと書いて実行ログで結果を見てもらうことを意図していました。

ともかく、 タスクの実行エラーに /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb と出ているので、普段の Ruby ではなくシステムの Ruby が使われていることは分かりました。

config/schedule.rb を修正したあとで bundle exec whenever --update-crontab を実行し忘れているのではないでしょうか。

0Like

@usai 
ご返信ありがとうございます。

色々とご教示頂き、ありがとうございます。
config/schedule.rbですが、下記のコードに編集して「bundle exec whenever --update-crontab」を行いましたが、同じエラーが出てしまう状態になります。
何度も申し訳ありませんが、他にお気づきな点がありましたらよろしくお願いいたします。

require File.expand_path(File.dirname(__FILE__) + '/environment')
env 'PATH', ENV['PATH']
rails_env = ENV['RAILS_ENV'] || :development
set :output, "#{Rails.root}/log/cron.log"
# ジョブの実行環境の指定
set :environment, rails_env

every 1.minutes do
 rake "thanxmailer_a:thanxmailer_a" 
end

※runner "ThanxMailer.a.deliver_nowを、rake "thanxmailer_a:thanxmailer_a" に変更しました。

namespace :thanxmailer_a do
  desc '定期テスト'
  task thanxmailer_a: :environment do
    ThanxMailer.a.deliver_now
  end
 end
0Like

env 'PATH', ENV['PATH'] を消して、代わりに

set :path_env, ENV['PATH']
job_type :runner, "cd :path && PATH=':path_env' bin/rails runner -e :environment ':task' :output"

と書いて bundle exec whenever --update-crontab を実行してみてください。

0Like

@usai 
ご返信ありがとうございます。

ご教示頂きました通り、下記のように修正させて頂き、「bundle exec whenever --update-crontab」を行いました。

require File.expand_path(File.dirname(__FILE__) + '/environment')
set :path_env, ENV['PATH']
job_type :runner, "cd :path && PATH=':path_env' bin/rails runner -e :environment ':task' :output"
rails_env = ENV['RAILS_ENV'] || :development
set :output, "#{Rails.root}/log/cron.log"
set :environment, rails_env

every 1.minutes do
  rake "thanxmailer_a:thanxmailer_a" 
end

再度、logには下記のエラーが表示されてしまいます。
何度も、申し訳ございません。。。

/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.1.4) required by your /Users/uot/projects/subscription/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.1.4`
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
    from /usr/bin/bundle:23:in `<main>'
0Like

起動しました!ありがとうございます!
明日、上記コードをもとにコードについて一つ一つ調べてみよう思います。
本当にありがとうございます。

0Like

上記コードをもとにコードについて一つ一つ調べてみよう思います。

job_type 行が何をしているかはこのあたりを読んでください。
https://github.com/javan/whenever#define-your-own-job-types

ジョブを rake "thanxmailer_a:thanxmailer_a" と定義すると、 job_type :rake, 'テンプレート...' のテンプレートに従ってコマンドに変換されます。

変換結果は bundle exec whenever を実行して crontab を表示すると見られます。だいたいこんな感じになると思います(左側の数字と * の部分は定期実行の間隔によって異なります):

0 * * * * /bin/bash -l -c 'cd /Users/略 && 変換後のコマンド'

ここで cron が実行するコマンドの全体は /bin/bash -l -c 'cd /Users/略 && 変換後のコマンド' です。 /bin/bash -l -c コマンドを使ってコマンド文字列を実行しているわけですが、これ自体が PATH 環境変数を上書きしてしまうので env 'PATH', ENV['PATH'] ではうまくいかなかったようです。

job_type による設定では 変換後のコマンド の位置であらためて PATH をセットするようにしたのでうまくいっています。

0Like

ご丁寧にありがとうございます!
今回で自分の理解できてない箇所がたくさんありました。

頂いた内容を参考に、理解を深めていきます。

0Like

Your answer might help someone💌