【Rails】bcryptインストール時の"cannot load such file -- bcrypt_ext"エラー対応【Windows】

Ruby on Railsのチュートリアルの6章をしていた際に、`bcrypt`をインストールしようとしてタイトルのエラーが出てはまったので、備忘録として残しておきます。

# 環境
今回のエラーが発生した環境です。

- ruby 2.4.1p111 (2017-03-22 revision 58053) [x64-mingw32]
- Rails 5.1.2
- Windows 7 Professional 64bit

# 解決策
解決策だけ知りたい人もいると思うので、先に載せておきます。

結果的に以下のissueコメントが解決策となりました。
https://github.com/codahale/bcrypt-ruby/issues/142#issuecomment-291345799


1. `gem uninstall bcrypt` を実行
1. `gem uninstall bcrypt-ruby` を実行
1. `gem install bcrypt --platform=ruby`を実行
1. Gemfileに`gem 'bcrypt', '~> 3.1.11'`を記載
1. `bundle install`を実行

# 解決までの流れ

## 問題発生
Ruby on Railsチュートリアルでは6章のリスト6.36にて`bcrypt`のインストールを施されます。

```ruby
source 'https://rubygems.org'

gem 'rails',          '5.0.3'
gem 'bcrypt',         '3.1.11'
.
.
.
```

また、記載通りに`$ bundle install`をします。
その後、テスト結果を確認しようと`$ rails test`とすると、以下のエラーが発生。

```console
$ rails test
C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bcrypt-3.1.11-x64-mingw32/lib/bcrypt.rb:16:in `require': cannot load such file -- bcrypt_ext (LoadError)
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bcrypt-3.1.11-x64-mingw32/lib/bcrypt.rb:16:in `rescue in <top (required)>'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bcrypt-3.1.11-x64-mingw32/lib/bcrypt.rb:12:in `<top (required)>'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler/runtime.rb:82:in `require'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler/runtime.rb:82:in `block (2 levels) in require'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler/runtime.rb:77:in `each'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler/runtime.rb:77:in `block in require'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler/runtime.rb:66:in `each'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler/runtime.rb:66:in `require'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.1/lib/bundler.rb:108:in `require'
        from C:/Users/totto357/Documents/rails/sample_app/config/application.rb:7:in `<top (required)>'
        from C:/Users/totto357/Documents/rails/sample_app/config/environment.rb:2:in `require_relative'
        from C:/Users/totto357/Documents/rails/sample_app/config/environment.rb:2:in `<top (required)>'
        from C:/Users/totto357/Documents/rails/sample_app/test/test_helper.rb:1:in `require'
        from C:/Users/totto357/Documents/rails/sample_app/test/test_helper.rb:1:in `<top (required)>'
        from C:/Users/totto357/Documents/rails/sample_app/test/controllers/static_pages_controller_test.rb:1:in `require'
        from C:/Users/totto357/Documents/rails/sample_app/test/controllers/static_pages_controller_test.rb:1:in `<top (required)>'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/railties-5.1.2/lib/rails/test_unit/test_requirer.rb:14:in `require'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/railties-5.1.2/lib/rails/test_unit/test_requirer.rb:14:in `block in require_files'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/railties-5.1.2/lib/rails/test_unit/test_requirer.rb:13:in `each'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/railties-5.1.2/lib/rails/test_unit/test_requirer.rb:13:in `require_files'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/railties-5.1.2/lib/rails/test_unit/minitest_plugin.rb:94:in `plugin_rails_init'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest.rb:81:in `block in init_plugins'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest.rb:79:in `each'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest.rb:79:in `init_plugins'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest.rb:130:in `run'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/railties-5.1.2/lib/rails/test_unit/minitest_plugin.rb:77:in `run'
        from C:/Ruby/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest.rb:63:in `block in autorun'
```

bcryptのインストールを確認してみると、インストールはされているみたい。(`x64-mingw32`は気になるが)

```console
.
.
.
Using turbolinks-source 5.0.3
Using multi_json 1.12.1
Using bcrypt 3.1.11 (x64-mingw32)
.
.
.
```

これだけでは解決策は分からないので、とりあえず1行目のエラー `cannot load such file bcrypt_ext` でぐぐってみます。

## 試行1

まず検索1位のQiitaの記事で参照しているissueコメントを試す。
http://qiita.com/toshikase/items/d04634c6157656300c72
https://github.com/codahale/bcrypt-ruby/issues/128#issuecomment-173361662

1. `gem uninstall bcrypt` を実行
1. `gem uninstall bcrypt-ruby` を実行
1. `gem install bcrypt --platform=ruby`を実行
1. Gemfileに`gem 'bcrypt-ruby', '3.1.5', :require => 'bcrypt'`を記載
1. `bundle install`を実行

結果、前回と同じように`bcrypt 3.1.11 (x64-mingw32)`がインストールされてしまい同じエラーに。

```console
.
.
.
Using multi_json 1.12.1
Fetching bcrypt 3.1.11 (x64-mingw32)
Installing bcrypt 3.1.11 (x64-mingw32)
.
.
.
```

また、`$ bundle install`のログの最後に以下のような警告?が表示されており、
`bcrypt-ruby`は`bcrypt`に名前が変わっていているみたい。

```console
#######################################################

The bcrypt-ruby gem has changed its name to just bcrypt.  Instead of
installing `bcrypt-ruby`, you should install `bcrypt`.  Please update your
dependencies accordingly.

#######################################################
```

## 試行2

試行1のissueの別のコメントを試す。
https://github.com/codahale/bcrypt-ruby/issues/128#issuecomment-312720135


1. `gem uninstall bcrypt` を実行
1. `gem uninstall bcrypt-ruby` を実行
1. `gem install bcrypt --platform=ruby`を実行
1. Gemfileに`gem 'bcrypt-ruby', '~> 3.1.7', platforms: [:ruby, :x64_mingw]`を記載
1. `bundle install`を実行

`bundle install`の時点で、以下のエラーで失敗。

```console
$ bundle install
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Could not find gem 'bcrypt-ruby (~> 3.1.7) x64-mingw32' in any of the gem
sources listed in your Gemfile.
```

Gemfileの記載を`gem 'bcrypt-ruby', '~> 3.1.7', platforms: [:ruby]`に変更してリトライ。
すると、`bundle install`は成功するがログを見ると`bcrypt`がインストールされてない。

念のため`rails test`もしてみるが、`bcrypt`がないよというエラーに。

```console
$ rails test
ansi: 'gem install win32console' to use color on Windows
Started with run options --seed 65497

You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install
ERROR["test_should_get_contact", StaticPagesControllerTest, 0.03690567500052566]
 test_should_get_contact#StaticPagesControllerTest (0.04s)
LoadError:         LoadError: cannot load such file -- bcrypt
            app/models/user.rb:13:in `<class:User>'
            app/models/user.rb:1:in `<top (required)>'
.
.
.
```

## さらにぐぐる

上記で見ていたissueよりも新しいissueがあったため、そちらを確認する。
すると解決策となったコメントを発見。
試してみると、無事解決！！


# まとめ

情報の鮮度は大事。(2016年の記事ならまだいけるだろと思った自分を殴りたい)
Gemfileに記載する`require`や`plarforms`がどういった意味があるのか調べる必要がある。

# 参考記事

https://railstutorial.jp/chapters/modeling_users?version=5.0#code-validates_uniqueness_of_email_case_insensitive_test
http://qiita.com/toshikase/items/d04634c6157656300c72
https://github.com/codahale/bcrypt-ruby/issues/128
https://github.com/codahale/bcrypt-ruby/issues/142