Ruby on Rails Tutorialを2015年2月最新バージョンの環境で進めたら...

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう

Ruby on Rails Tutorialを2015年2月最新バージョンの環境で進めたら、
こんな点でひっかかりました、というメモです。

チュートリアルに載っている環境は古いため、
どうせなら今後使用する環境に近いバージョンで、と考え、
あえて2015年2月最新バージョンで環境をセットアップしました。

その結果、主に以下の点でチュートリアルとは異なる環境となりました。

チュートリアルの環境>
Ruby 2.0.0
Rails 4.0.5
Bundler ?.?.?
rspec-rails 2.13.1
selenium-webdriver 2.35.1
Capybara 2.1.0
bootstrap 2.3
bcrypt-ruby 3.1.2
factory_girl_rails 4.2.1

<今回の環境>
Ruby 2.2.0
Rails 4.2.0
Bundler 1.8.2
rspec-rails 3.2.0
selenium-webdriver 2.44.0
Capybara 2.4.4
bootstrap-sass 3.3.3
sprockets 2.12.3
bcrypt-ruby 3.1.5
factory_girl_rails 4.4.1
rspec-its 1.2.0

◆ひっかかったポイントその1

「3.2.1 テスト駆動開発」で以下のコマンドを実行すると、

$ bundle exec rspec spec/requests/static_pages_spec.rb

以下のようなエラーになりました。

Failure/Error: visit '/static_pages/home'
     NoMethodError:
       undefined method `visit' for #<RSpec::ExampleGroups::StaticPages::HomePage:0x007fb6c8a41ce0>
1 example, 1 failures

以下のサイトによると、Capybaraをインストールしている場合はテストスクリプトはspec/features以下に置く必要があるとのこと。
RspecをRails 4.1で動かすまでの話 - Taught by Myself

spec/requests を spec/features にして再実行すると、

$ bundle exec rspec spec/features/static_pages_spec.rb

またしても前回と同じエラーです。

以下のサイトによると、、rspec-rails3系からrails_helper.rbが作られるようになり、
それに伴って、*_spec.rbの先頭は、
require 'spec_helper' ではなく、
require 'rails_helper' とする必要があるとのこと。
Rails4.1 with zeusでrspec3使おうとしたらいろいろハマった - Qiita

そこで、*_spec.rbを変更して再実行すると、

Failure/Error: expect(page).to have_content('Sample App')
       expected to find text "Sample App" in "StaticPages#home Find me in app/views/static_pages/home.html.erb"
1 example, 1 failures

正常に失敗です。TDDなので、これでOKです。
テストを通るようにhome.html.erbを書き換えてから再実行すると、

1 example, 0 failures

これで正常に成功です。(まぎらわしい。。)

ひっかかったポイントその1は以降、幾度となく出てきます。

◆ひっかかったポイントその2

「5.1.2BootstrapとカスタムCSS」、「5.1.3パーシャル (partial)」でチュートリアルのレイアウトと一致しません。

これは、単純にBootstrapの2系と3系の違いですね。Railsとは関係ないですが、一応書きます。次の2点を変更します。

(1)app/views/layouts/_header.html.erb を以下のように変更する。

<ul class="nav pull-right">

<ul class="nav navbar-nav navbar-right">

(2)app/views/static_pages/home.html.erb を以下のように変更する。

<div class="center herounit">

<div class="center jumbotron">

◆ひっかかったポイントその3

「5.2.2素晴らしい構文を備えたスタイルシート」で「Undefined variable: "$grayLight".」などのエラーになります。

以下のサイトによると、これもBootstrapの2系と3系の違いのようです。

After update to 3.0.0 - Undefined variable: "$grayLight". · Issue #463 · twbs/bootstrap-sass · GitHub

color: $grayLight; は
color: $gray-light; に変更して、
color: $grayDarker; は
color: $gray-darker; に変更するとエラーは消えます。

「7.1.4gravatar画像とサイドバー」でも
$grayLighter; が出てきますので、
$gray-lighter; と変更すると成功します。

◆ひっかかったポイントその4

「5.3.4RSpecを洗練させる」でspec/support/utilities.rbを作成してテストするところで「undefined method `full_title'」のエラーになります。

以下のサイトによると、rspecの2系と3系の違いのようです。

Rails - RSpec3でspec/support内のファイルを読み込む - Qiita

チュートリアルでは「spec/supportディレクトリはRSpecによって自動的に読み込まれる」と書かれていますが、それはどうも2系の話のようで、3系では自動的に読み込まれないようです。
spec/rails_helper.rb の
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
コメントアウトを外すと、spec/supportディレクトリは自動的に読み込まれるようになり、エラーは消えます。

◆ひっかかったポイントその5

「6.3.3ユーザー認証」において、誤ったパスワードで認証しようとしたらfalseになることを確認するテストを書きますが、チュートリアルの通りに書いてテストを実行すると、「Failure/Error: specify { expect(user_for_invalid_password).to be_false } expected false to respond to `false?`」エラーになります。

これはRSpec2系と3系の違いによるもので、以下のように変更してテストを実行すると通ります。

be_false

be_falsy

◆ひっかかったポイントその6

「7.2.2form_forを使用する」において、以下のようにdescriptionの部分文字列を指定してテストを実行しますが、思うように対象のテストが実行されません。

$ bundle exec rspec spec/requests/user_pages_spec.rb -e "signup page"

どうやらチュートリアルtypoのようです。「7.2.1ユーザー登録のためのテスト」でテストのdescriptionが"signup page"ではなく、"signup"となっていました。そのため、以前の別の"signup"のテストまで実行されてしまっていました。

◆ひっかかったポイントその7

「7.2.2form_forを使用する」において、テストをパスするはずとされているテストが2つパスせず、2つとも「The action 'create' could not be found for UsersController」というエラーになります。

app/controllers/users_controller.rbを確認すると、確かにcreateはありません。読み落としていないかチュートリアルを検索してみたところ、以前の章ではなく、これから読み進める「7.3.1正しいフォーム」においてcreateは実装するようでした。そのため、ここはエラーのままで、次へ進むことにします。

◆ひっかかったポイントその8

「7.3.3ユーザー登録のエラーメッセージ」で、Bootstrapの2系と3系の違いから、チュートリアル通りにすると以下のエラーになります。

The selector ".control-group" was not found.
The selector ".error" was not found.

それぞれ、app/assets/stylesheets/custom.css.scssを以下のように修正します。

@extend .control-group

@extend .form-group
@extend .error

@extend .has-error

これでエラーはなくなりますが、.has-errorのスタイルはなくなったらしく表示に反映されません。詳しくは以下の記事を参照してください。
Railsのfield_with_errorsクラスにBootstrap3を適用 - Qiita

◆ひっかかったポイントその9

「8.2.1[このアカウント設定を保存する]」で、`method_missing': undefined method `its'というエラーが発生します。
itsメソッドはrspec3ではなくなり、rpsec-itsに分けられたようです。

gem rspec-its

として、bundle installすると、rspec-its 1.2.0が入り、テストも成功しました。

チュートリアルを完了するまで結構かかりそうなので進んだところまでを都度更新します。6/15現在、8.2.1です。