頭の中は異空間

ものづくり中心

新しいgemを入れる(+Ruby Version Upgrade)時に気をつけること

どうも。

 

Railsで様々なgemを追加する機会がありますが、その度に依存性に困らされた経験を持つ人は多いと思います。自分もその一人で、何度も都度調べるのも面倒だと思ったので覚書として手順とそれぞれの役割を簡単にまとめます。

 


Gemfile修正

ここに定義されているgemが、開発時に使えるgemのリストになります。中には明示的に ~>2.0のようにバージョン指定されているgemもあり、このバージョンで無いと動かない、というgemも存在します。基本的にデフォルトのバージョン指定はいじらない方がいいでしょう。

Rubyを使う以上はひたすらこの依存性と付き合っていかなくてはいけないので、なんとなく、ではなく流れ、仕組みを詳細に知っておくべきでしょう。

まだ定義されていないgemはここにgem gemモジュール名と記載して読み込まれるようにする必要があります。

 

Gemfileをいじったら、いよいよダウンロード&インストールの準備です。当然、ネット繋がってないと失敗します。

 

bundle install

追加したgemをインストールするのに 必要です。

==> ここが参考になる

qiita.com

 

bundle update

これは単体で実行すると危険と言われますが、それはすべてgem同士の依存関係の問題からきています。特定のgemの特定のバージョンに依存したgemがある場合、すべてを一度に最新にでもしようとすれば動作しなくなるのは当たり前。 

これは適宜やるというよりは、何らかのgemのinstallをするのに現行では依存関係上まずいときなど、必要に応じてやるべきかと。

引数にgem名を渡すことで、特定のgemだけをupdateできます。

 

brew update

パッケージ管理システム。

==> ここがわかりやすい

homebrewとは何者か。仕組みについて調べてみた - Qiita

RubyだけでなくJavaやその他機能をパッケージ単位でダウンロード&インストールしてくれるツール。どちらかというとlinuxの考え方に近いか。centOSでいうyum, Ubuntuでいうapt-getといえば通じますかね。

そしてこの”brew”自体もソフトウェアであり、updateする必要があります。そんな時にbrew updateとかします。

==> こけたら下記を参照。

http://spring-mt.tumblr.com/post/18484480866/homebrewのbrew-updateでこけた件

spring-mt.tumblr.com

 

rbenv

通常は、ruby-buildとともに使用する。中にはgemのバージョンだけでなく、Rubyのバージョンのせいで動作しないgem(ログイン認証に用いるdeviseとか)もあります。そんな時はRuby自体をupdateする必要に迫られますので、合わせて載せちゃいます。

Rubyの新バージョンをインストールするには

rbenv install Rubyのバージョン名

で狙ったバージョンをインストールしましょう。

 

私はruby2.2.4をインストールしました。

ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin15]

rbenv versions
  system
  2.0.0-p451
* 2.2.4 (set by RAILS_ROOTのパス/.ruby-version

Rubyのinstall後もまだ安心はできません。Rails Consoleを立ち上げようとしたら、bundler関連で、下記のように怒られました(´・ω・`)

rbenv: rails: command not found

The `rails' command exists in these Ruby versions:
  2.0.0-p451
  

2.2.4がNEEEEEE!!

そもそも、bundle installのbundlerというのもソフトウェアです。これ自体のバージョンも関係している模様で、それが利用中のRubyのバージョンとあっていないと怒られるとのこと。

==> 下記を参照

shiro-16.hatenablog.com

 

じゃあ、仕方ないから、bundlerも入れ直しましょう。※1

bundle install

今度は大丈夫なはず。

rails c
rbenv: rails: command not found

The `rails' command exists in these Ruby versions:
  2.0.0-p451

が、駄目っ・・・!

よくよくエラーメッセージを見ると、railsを入れ直す必要がありました。時間がかかるな〜(´・ω・`)

gem install rails

さて様子は?

rails c

Running via Spring preloader in process 43023
RAILS_ROOTのパス/vendor/bundle/ruby/2.2.0/gems/spring-1.7.1/lib/spring/application.rb:175: warning: Insecure world writable dir RAILS_ROOTのパス in PATH, mode 040757
Loading development environment (Rails 4.2.4)
2.2.0 :001 >

よし、成功。

最終的にそれぞれのパッケージのバージョンは下記の通りになりました。

rails -v
  Rails 4.2.4

ruby -v
  ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin15]

rbenv -v
  rbenv 1.0.0

bundler -v
  Bundler version 1.12.5

いやぁ〜長い戦いだった。。

そもそもこのタイミングでRubyバージョン変更するとは思わなんだ。deviseっていうgemを入れるために追加で苦労する羽目になったが、基本を押さえておけばトラブったところで無問題。この程度の障害で俺を超えることはできぬぅ!

 

rvm

Rubyをインストールして共存させたいときに用いるパッケージです。Rubyは他の言語以上にバージョンによる制限というか影響が大きいので、同時に複数のバージョンを使えるようにしておきたいという要望は多いんでしょう。

ここだけだと、rbenv(+ruby-build)とかぶりますが、単にRubyをインストールするだけならこちらでもいいでしょう。基本的にrvmでできることはrbenvに必要なgemsetを追加すればいいんですが、いちいち調べるのも面倒でしょうから。

==> 細かな違いは下記参照。

http://passingloop.tumblr.com/post/10512902196/difference-between-rbenv-and-rvm

passingloop.tumblr.com

 

 


最大の注意点

※1の部分で、実はさらにこけていました。rbenvとrvmの両刀は危険ということです。あろうことか私はrbenvで入れたRubyをなぜかrvmで入れなおしてしまい、おかげで正しくBundlerが立ち上がらなくなってしまいました。

bundle -v

/Users/ユーザ名/.rbenv/versions/2.2.4/lib/ruby/2.2.0/rubygems/dependency.rb:315:in `to_specs': Could not find 'bundler' (>= 0) among 14 total gem(s) (Gem::LoadError)
Checked in 'GEM_PATH=/Users/ユーザ名/.rvm/gems/ruby-2.2.4:/Users/ユーザ名/.rvm/gems/ruby-2.2.4@global', execute `gem env` for more information
	from /Users/ユーザ名/.rbenv/versions/2.2.4/lib/ruby/2.2.0/rubygems/dependency.rb:324:in `to_spec'
	from /Users/ユーザ名/.rbenv/versions/2.2.4/lib/ruby/2.2.0/rubygems/core_ext/kernel_gem.rb:64:in `gem'
	from /Users/ユーザ名/.rbenv/versions/2.2.4/bin/bundle:22:in `<main>'
</main>

上記エラー内容にrvm、とあるので原因は明らか。こうなってしまったら、解決策は

gem install bundler

はい、入れ直しです。どれだけこければ気が済むんだ><

==> この問題に関しては先駆者がいました。StackOverflow万歳ヽ('A`)ノ

stackoverflow.com

 

bundle -v

Bundler version 1.12.5

今度はこけませんでした。

 

上記の様にbundler周りで色々こけている場合、他にも影響している可能性が考えられます。案の定、私の場合はrakeコマンドが死んでました

というわけで解決します。

rake routes

rake aborted!
Gem::LoadError: You have already activated rake 10.4.2, but your Gemfile requires rake 11.1.2. Prepending `bundle exec` to your command may solve this.
/Users/ユーザ名/.rvm/gems/ruby-2.2.4/gems/bundler-1.12.5/lib/bundler/runtime.rb:35:in `block in setup'
...

こういうエラーが出たら、bundle execをつけてコマンド実行すれば、エラーは出ません。

bundle exec rake routes

     Prefix Verb   URI Pattern                Controller#Action
maker_index GET    /maker/index(.:format)     maker#index
       root GET    /                          maker#index
     makers GET    /makers(.:format)          makers#index
            POST   /makers(.:format)          makers#create
  new_maker GET    /makers/new(.:format)      makers#new
 edit_maker GET    /makers/:id/edit(.:format) makers#edit
      maker GET    /makers/:id(.:format)      makers#show
            PATCH  /makers/:id(.:format)      makers#update
            PUT    /makers/:id(.:format)      makers#update
            DELETE /makers/:id(.:format)      makers#destroy

うん、動いた。

ただ、これは毎回頭にbunldle execつけないといけないっぽいな(´・ω・`)そもそもbundlerを更新しただけで死ぬって設計思想からしてどうかと思うんだがな。。

エラー内容とその解決方法自体は他のどんなパッケージも、同様。落ちる原因はまず間違いなくバージョンによる依存関係の問題だから、どれとどれのバージョンの関係に問題があるのかをはっきりさせましょう。

 


ここに至るまでに本当にQiitaには度々お世話になりっぱなしで、最高にありがたいサイトだと思います。考案者は天才。

そしてこれだけ地雷を踏んだんだから、その経験はこうしてある意味啓蒙活動として広める&記録に残すのは義務だと思っているので、時間をかけてでもまとめ上げるのは結構楽しいものです。これからも続けていきます。

 

これで何度もググり直す必要がなくなるだろう。