読者です 読者をやめる 読者になる 読者になる

新米パパの育児留学

子供との幸せな時間を今だけではなく、一生大切にしたいという思いから、育休中にプログラミングを学習しエンジニアを目指します。

【第11章】Ruby on Rails チュートリアル 5.0(第4版)演習と解答まとめ

プログラミング プログラミング-Rails_チュートリアル

Ruby on Rails Tutorial最新版の演習と解答です。

f:id:mochikichi321:20170206212242p:plain

目的

Ruby on Rails チュートリアル 5.0(第4版)を学習中です。

学習を進める中で演習問題の解答がなかった(*1,2)ので、自分なりにまとめていくこととしました。

アウトプットし、自分の理解を深めることを目的としています。 もし、記載内容に誤りがあった場合はコメントいただけると幸いです。

(*1)著者による有償版の解答はあるようです。正式な解答をご希望の方はこちらを参照ください。

Learn Web Development with Rails: Michael Hartl's Ruby on Rails Tutorial | Softcover.io

(*2)旧版に関する解答はありましたが、最新版 5.0(第4版)に関しては検索しても出てきませんでした。

プログラミングを学習し始めたきっかけについてはこちら

mochikichi.hatenablog.com

演習問題と解答

演習11.1.1

演習11.1.1.1

<問題> 現時点でテストスイートを実行すると greenになることを確認してみましょう。

<解答> 動作確認のみなので省略。

演習11.1.1.2

<問題> 表 11.2の名前付きルートでは、pathではなくurlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: 私達はこれからメールで名前付きルートを使います。

<解答> メールのURLからアクセスするため。

演習11.1.2

演習11.1.2.1

<問題> 本項での変更を加えた後、テストスイートが green のままになっていることを確認してみましょう。

<解答> 動作確認のみなので省略。

演習11.1.2.2

<問題> コンソールからUserクラスのインスタンスを生成し、そのオブジェクトからcreate_activation_digestメソッドを呼び出そうとすると (Privateメソッドなので) NoMethodErrorが発生することを確認してみましょう。また、そのUserオブジェクトからダイジェストの値も確認してみましょう。

<解答> 動作確認のみなので省略。

演習11.1.2.3

<問題> リスト 6.34で、メールアドレスの小文字化にはemail.downcase!という (代入せずに済む) メソッドがあることを知りました。このメソッドを使って、リスト 11.3のdowncase_emailメソッドを改良してみてください。また、うまく変更できれば、テストスイートは成功したままになっていることも確認してみてください。

<解答>

[user.rb]

class User < ApplicationRecord
  attr_accessor :remember_token, :activation_token
  before_save { email.downcase! }  <---注目
(中略)

  private

    # メールアドレスをすべて小文字にする
    # def downcase_email                 <---不要
    #   self.email = email.downcase
    # end
(中略)
end

テストはGREEN。

演習11.2.1

演習11.2.1.1

<問題> コンソールを開き、CGIモジュールのescapeメソッド (リスト 11.15) でメールアドレスの文字列をエスケープできることを確認してみましょう。このメソッドで"Don’t panic!“をエスケープすると、どんな結果になりますか?

<解答>

>> CGI.escape('Don’t panic!')
=> "Don%E2%80%99t+panic%21"

演習11.2.2

演習11.2.2.1

<問題> Railsプレビュー機能を使って、ブラウザから先ほどのメールを表示してみてください。「Date」の欄にはどんな内容が表示されているでしょうか?

<解答> Dateはブラウザでメールを表示した時点の日時。

演習11.2.3

演習11.2.3.1

<問題> この時点で、テストスイートが greenになっていることを確認してみましょう。

<解答> 動作確認のみなので省略。

演習11.2.3.2

<問題> リスト 11.20で使ったCGI.escapeの部分を削除すると、テストが redに変わることを確認してみましょう。

<解答> 動作確認のみなので省略。

演習11.2.4

演習11.2.4.1

<問題> 新しいユーザーを登録したとき、リダイレクト先が適切なURLに変わったことを確認してみましょう。その後、Railsサーバーのログから送信メールの内容を確認してみてください。有効化トークンの値はどうなっていますか?

<解答>

https://rails-tutorial-mhartl.c9users.io/account_activations/wGEP2viu2WQbS9n36A41Lg/edit?email=2%40gmail.com

演習11.2.4.2

<問題> コンソールを開き、データベース上にユーザーが作成されたことを確認してみましょう。また、このユーザーはデータベース上にはいますが、有効化のステータスがfalseのままになっていることを確認してください。

<解答> 動作確認のみなので省略。

演習11.3.1

演習11.3.1.1

<問題> コンソール内で新しいユーザーを作成してみてください。新しいユーザーの記憶トークンと有効化トークンはどのような値になっているでしょうか? また、各トークンに対応するダイジェストの値はどうなっているでしょうか?

<解答> 動作確認のみなので省略。

演習11.3.1.2

<問題> リスト 11.26で抽象化したauthenticated?メソッドを使って、先ほどの各トークン/ダイジェストの組み合わせで認証が成功することを確認してみましょう。

<解答> 動作確認のみなので省略。

演習11.3.2

演習11.3.2.1

<問題> コンソールから、11.2.4で生成したメールに含まれているURLを調べてみてください。URL内のどこに有効化トークンが含まれているでしょうか?

<解答>

https://rails-tutorial-mhartl.c9users.io/account_activations/wGEP2viu2WQbS9n36A41Lg/edit?email=2%40gmail.com

“wGEP2viu2WQbS9n36A41Lg"が有効化トークン。

演習11.3.2.2

<問題> 先ほど見つけたURLをブラウザに貼り付けて、そのユーザーの認証に成功し、有効化できることを確認してみましょう。また、有効化ステータスがtrueになっていることをコンソールから確認してみてください。

<解答> 動作確認のみなので省略。

演習11.3.3

演習11.3.3.1

<問題> リスト 11.35にあるactivateメソッドはupdate_attributeを2回呼び出していますが、これは各行で1回ずつデータベースへ問い合わせしていることになります。リスト 11.39に記したテンプレートを使って、update_attributeの呼び出しを1回のupdate_columns呼び出しにまとめてみましょう (これでデータベースへの問い合わせが1回で済むようになります)。また、変更後にテストを実行し、 greenになることも確認してください。

<解答>

[user.rb]

class User < ApplicationRecord

(中略)

  # アカウントを有効にする
  def activate
    update_columns(activated: true, activated_at: Time.zone.now)
  end

(後略)

演習11.3.3.2

<問題> 現在は、/usersのユーザーindexページを開くとすべてのユーザーが表示され、/users/:idのようにIDを指定すると個別のユーザーを表示できます。しかし考えてみれば、有効でないユーザーは表示する意味がありません。そこで、リスト 11.40のテンプレートを使って、この動作を変更してみましょう8。なお、ここで使っているActive Recordのwhereメソッドについては、13.3.3でもう少し詳しく説明します。

<解答>

[users_controller.rb]

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: :destroy
  
  def index
    @users = User.where(activated: true).paginate(page: params[:page])
  end

  def show
    @user = User.find(params[:id])
    redirect_to root_url and return unless @user.activated?
  end

(後略)

演習11.4

演習11.4.1

<問題> 実際に本番環境でユーザー登録をしてみましょう。ユーザー登録時に入力したメールアドレスにメールは届きましたか?

<解答> 動作確認のみなので省略。

演習11.4.2

<問題> メールを受信できたら、実際にメールをクリックしてアカウントを有効化してみましょう。また、Heroku上のログを調べてみて、有効化に関するログがどうなっているのか調べてみてください。ヒント: ターミナルからheroku logsコマンドを実行してみましょう。

<解答> 動作確認のみなので省略。

<a href="https://&lt;your heroku app&gt;.herokuapp.com/account_activations/uiXkg8zRNKlluX3pX7-vwg/edit?email=mochikichi%40live.jp">Activate</a>

関連記事

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com

mochikichi.hatenablog.com