## 前回の分からなかったこと テスト駆動開発とは??? <u><a href="https://teratail.com/questions/121833" target="_blank">ここ</a></u>を見たが、まあ、経験を踏めばわかってくる概念であり、分かりにくいことが分かった。チュートリアルを通してもっと深く理解していきたい。   # 7章 ## デバックとrails環境 サイトのレイアウトにデバック情報を追加する。 **app/views/layouts/application.html.erb** ```html <%= debug(params) if Rails.env.development? %> ``` ビルトインのdebugメソッドとparams変数を使って、各プロフィールページにデバッグ用の情報が表示されるようにする。 **.development?** で、Railsの3つのデフォルト環境のうち、開発環境 (development) だけで表示されるようになる。   3つのデフォルト環境の使い分けについてだが、 ・普段のrails consoleでは、 ```bash $ rails console Loading development environment >> Rails.env => "development" >> Rails.env.development? => true >> Rails.env.test? => false ``` development環境である。   ・テスト環境のデバッグなど、他の環境でconsoleを実行する必要が生じた場合は、環境をパラメータ(変数)としてconsoleスクリプト(即座に実行できるプログラム)に渡すことができる。 ```bash $ rails console test Loading test environment >> Rails.env => "test" >> Rails.env.test? => true ``` ・Herokuは本番サイト用のプラットフォームなので、実行されるアプリケーションはすべて本番環境となる。 ```bash $ heroku run rails console >> Rails.env => "production" >> Rails.env.production? => true ``` 詳しくは<u><a href="https://railstutorial.jp/chapters/sign_up?version=5.1#sec-rails_environments" target="_blank">コラム7.1</a></u>を見てください。   次にデバック表示を整形する。 **app/assets/stylesheets/custom.scss** ```scss @import "bootstrap-sprockets"; @import "bootstrap"; /* mixins, variables, etc. */ $gray-medium-light: #eaeaea; @mixin box_sizing { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } . . . /* miscellaneous */ .debug_dump { clear: both; float: left; width: 100%; margin-top: 45px; @include box_sizing; /*定義したミックスイン*/ } ``` Sassのミックスインという機能が使われている。パッケージ化して、閣僚を減らす。見やすくする。 表示されたデバック出力には描画されたページの情報が含まれる。この **params** の内容は **YAML** という形式で書かれている。基本的にハッシュで、人間だけではなく、このコンピュータにとっても読みやすい形式。   ## 演習 1.ブラウザから /about にアクセスし、デバッグ情報が表示されていることを確認してください。このページを表示するとき、どのコントローラとアクションが使われていたでしょうか? paramsの内容から確認してみましょう。 A. デバック出力は以下のようになる。 ```string --- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess controller: static_pages action: about permitted: false ``` static_pagesコントローラのaboutアクションが使われたことが分かる。   2.Railsコンソールを開き、データベースから最初のユーザー情報を取得し、変数userに格納してください。その後、puts user.attributes.to_yamlを実行すると何が表示されますか? ここで表示された結果と、yメソッドを使ったy user.attributesの実行結果を比較してみましょう。 A. まずは、findメソッドを使い、userに代入 ```bash user = User.find(1) User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] => #<User id: 1, name: "Takukin", email: "mhartl@example.com", created_at: "2020-01-17 11:27:03", updated_at: "2020-01-18 05:35:38", password_digest: "$2a$10$ZhxNCTARw/sPxesOSdbX2.1bQpTioIhOYk6WvXISOUO..."> ``` 次に、 **puts user.attributes.to_yaml** ```bash --- id: 1 name: Takukin email: mhartl@example.com created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2020-01-17 11:27:03.438851000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone name: Etc/UTC time: *1 updated_at: !ruby/object:ActiveSupport::TimeWithZone utc: &3 2020-01-18 05:35:38.851927000 Z zone: *2 time: *3 password_digest: "$2a$10$ZhxNCTARw/sPxesOSdbX2.1bQpTioIhOYk6WvXISOUOYSD2o/l/5e" => nil ``` 次に、 **y user.attributes** ```bash --- id: 1 name: Takukin email: mhartl@example.com created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2020-01-17 11:27:03.438851000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone name: Etc/UTC time: *1 updated_at: !ruby/object:ActiveSupport::TimeWithZone utc: &3 2020-01-18 05:35:38.851927000 Z zone: *2 time: *3 password_digest: "$2a$10$ZhxNCTARw/sPxesOSdbX2.1bQpTioIhOYk6WvXISOUOYSD2o/l/5e" => nil ``` 出力結果は、 **puts user.attributes.to_yamlとy user.attributesは一緒。**   ## Userリソース データの作成、表示、更新、削除をリソース(Resourceとして扱えるようにする。 **config/routes.rb** ```ruby resources :users ``` これを **リソースルーティング** と呼ぶらしい。これを使うことによって、コントローラの **index、show、new、edit、create、update、destroyアクション** を個別に宣言しなくても1行で宣言が完了。これにより、今回の場合、 ***/users/1*** にアクセスできる。 しかし、 ルーティングテーブルは作れるが、ジェネレーターを使ってないので、アクションとビューは自分で作らなければならない。   まず、 **app/views/users/show.html.erb** にビューファイルを手動で作る。 **app/views/users/show.html.erb** ```html <%= @user.name %>, <%= @user.email %> ```   次に、Userコントローラにshowアクションを定義。 **app/controllers/users_controller.rb** ```ruby class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new end end ``` これで、 ***/users/1*** にアクセスできる。   ## 演習 1.埋め込みRubyを使って、マジックカラム (created_atとupdated_at) の値をshowページに表示してみましょう (リスト 7.4)。 A. **app/views/users/show.html.erb** ```ruby <%= @user.name %>, <%= @user.email %>, <%= @user.created_at %>, <%= @user.updated_at %> ``` のように、マジックカラム (created_atとupdated_at)を追加。   2.埋め込みRubyを使って、Time.nowの結果をshowページに表示してみましょう。ページを更新すると、その結果はどう変わっていますか? 確認してみてください。 A. **app/views/users/show.html.erb** ```ruby <%= @user.name %>, <%= @user.email %>, <%= @user.created_at %>, <%= @user.updated_at %>, <%= Time.now %> ``` のように、埋め込みRubyでTime.nowを追加。ブラウザを更新した時間が表示される。   ## debuggerメソッド もっと直接的にデバックする。 **byebug gemによるdebuggerメソッド** 使い方は直接debuggerをUserコントローラに差し込む。 **app/controllers/users_controller.rb** ```ruby class UsersController < ApplicationController def show @user = User.find(params[:id]) debugger end def new end end ``` そうして、ブラウザから /users/1 にアクセスし、Railsサーバーを立ち上げたターミナルを見て(byebug)というプロンプトがあれば成功。 ここで、Windows民はエラーを吐くので<u><a href="https://qiita.com/kusano_pg/items/eb38466f70dc05238fdb" target="_blank">ここで改善するとできるよ</a></u>gemのインストール。   (byebug)はRailsコンソールのようにコマンドを呼び出すことができて、アプリケーションのdebuggerが呼び出された瞬間の状態を確認することができる。 ```bash (byebug) @user.name "Takukin" (byebug) @user.email "mhartl@example.com" (byebug) params[:id] "1" ``` Ctrl-Dを押すとプロンプトから抜け出すことができる。もう必要ないので消しておく。わからないことがあったらdebuggerを差し込んで、アプリケーション内のエラーを追跡したりデバッグするのがコツ。    ## 演習 1.showアクションの中にdebuggerを差し込み (リスト 7.6)、ブラウザから /users/1 にアクセスしてみましょう。その後コンソールに移り、putsメソッドを使ってparamsハッシュの中身をYAML形式で表示してみましょう。ヒント: 7.1.1.1の演習を参考にしてください。その演習ではdebugメソッドで表示したデバッグ情報を、どのようにしてYAML形式で表示していたでしょうか? A. ```bash ((byebug) puts params.to_yaml --- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess controller: users action: show id: '1' permitted: false nil ```   2.newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。 A. **/app/controllers/users_controller.rb** ```ruby def new debugger end ``` byebugにて ```bash (byebug) @user nil ``` となる。   ## Gravatar画像とサイドバー **Gravatarとは** :無料のサービスで、プロフィール写真をアップロードして、指定したメールアドレスと関連付けることができるもの。   まずはビューから **app/views/users/show.html.erb** ```html <% provide(:title, @user.name) %> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> ```    次に、ヘルパーメソッドを定義する。ヘルパーファイルのどこでも定義できるが、分かりやすくするため、usersのヘルパーファイルにする。 **app/helpers/users_helper.rb** ```ruby module UsersHelper # 引数で与えられたユーザーのGravatar画像を返す def gravatar_for(user) gravatar_id = Digest::MD5::hexdigest(user.email.downcase) gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}" image_tag(gravatar_url, alt: user.name, class: "gravatar") end end ``` gravatar_idの定義はuserのemailをハッシュ化してgravatarのURLで使えるようにし、gravatar_urlで画像を取ってくるイメージ?? alt属性を入れることでブラウザが読み上げてくれる。     デフォルトのメールアドレスをコンソール上で変え、デザインも整える。 **rails c** ```bash $ rails console >> user = User.first >> user.update_attributes(name: "Example User", ?> email: "example@railstutorial.org", ?> password: "foobar", ?> password_confirmation: "foobar") => true ``` よって。ロゴが変わる。   デザインも変える。 **app/views/users/show.html.erb** ```html <% provide(:title, @user.name) %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> </section> </aside> </div> ``` ここでてくる、 **rowやcol-md-4クラス** はbootstrapで定義されたクラス名。   CSSも追加。 **app/assets/stylesheets/custom.scss** ```css /* sidebar */ aside { section.user_info { margin-top: 20px; } section { padding: 10px 0; margin-top: 20px; &:first-child { border: 0; padding-top: 0; } span { display: block; margin-bottom: 3px; line-height: 1; } h1 { font-size: 1.4em; text-align: left; letter-spacing: -1px; margin-bottom: 3px; margin-top: 0px; } } } .gravatar { float: left; margin-right: 10px; } .gravatar_edit { margin-top: 15px; } ```   ## 演習 1,(任意) Gravatar上にアカウントを作成し、あなたのメールアドレスと適当な画像を紐付けてみてください。メールアドレスをMD5ハッシュ化して、紐付けた画像がちゃんと表示されるかどうか試してみましょう。 A. <u><a href="https://ja.gravatar.com/" target="_blank">Gravatar</a></u>にて、アカウントを作り、プロフィール画像を設定して、rails console上でサンプルデータ(User.first)のメールアドレスを登録したアドレスに変更したらできた。   2.7.1.4で定義したgravatar_forヘルパーをリスト 7.12のように変更して、sizeをオプション引数として受け取れるようにしてみましょう。うまく変更できると、gravatar_for user, size: 50といった呼び出し方ができるようになります。重要: この改善したヘルパーは10.3.1で実際に使います。忘れずに実装しておきましょう。 A. コピペ。   3.オプション引数は今でもRubyコミュニティで一般的に使われていますが、Ruby 2.0から導入された新機能「キーワード引数 (Keyword Arguments)」でも実現することができます。先ほど変更したリスト 7.12を、リスト 7.13のように置き換えてもうまく動くことを確認してみましょう。この2つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。 A. コピペ。   ## ユーザ登録フォーム ## form_forを使用する **form_for** :ヘルパーメソッド。Active Recordのオブジェクトを取り込み、そのオブジェクトの属性を使ってフォームを構築する。 まずは、newアクションに@user変数を追加。 **app/controllers/users_controller.rb** ```ruby class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new @user = User.new end end ```   次に、HTML、CSSの変更。 **app/views/users/new.html.erb** ```html <% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_for(@user) do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.email_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation %> <%= f.submit "Create my account", class: "btn btn-primary" %> <% end %> </div> </div> ```   CSSに追加。 **app/assets/stylesheets/custom.scss** ```css /* forms */ input, textarea, select, .uneditable-input { border: 1px solid #bbb; width: 100%; margin-bottom: 15px; @include box_sizing; } input { height: auto !important; } ``` 開設は次のトピックでやるらしい。   ## 演習 1.試しに、リスト 7.15にある:nameを:nomeに置き換えてみましょう。どんなエラーメッセージが表示されるようになりますか? A. **NoMethodError in Users#new** **undefined method `nome'**   2.試しに、ブロックの変数fをすべてfoobarに置き換えてみて、結果が変わらないことを確認してみてください。確かに結果は変わりませんが、変数名をfoobarとするのはあまり良い変更ではなさそうですね。その理由について考えてみてください。 A. 結果は変わらない。 メタ構文変数(意味を持たない名前)として認識されるため、日本語では「ほにゃらら」などの意味で、変数名としてふさわしくないため。   ## フォームHTML 前のHTMLの設定 **app/views/users/new.html.erb** ```html <% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_for(@user) do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.email_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation %> <%= f.submit "Create my account", class: "btn btn-primary" %> <% end %> </div> </div> ``` は、ブラウザで以下のように置換される。 ```html <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post"> <input name="utf8" type="hidden" value="&#x2713;" /> <input name="authenticity_token" type="hidden" value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" /> <label for="user_name">Name</label> <input id="user_name" name="user[name]" type="text" /> <label for="user_email">Email</label> <input id="user_email" name="user[email]" type="email" /> <label for="user_password">Password</label> <input id="user_password" name="user[password]" type="password" /> <label for="user_password_confirmation">Confirmation</label> <input id="user_password_confirmation" name="user[password_confirmation]" type="password" /> <input class="btn btn-primary" name="commit" type="submit" value="Create my account" /> </form> ``` 変換された後に以下のコードが加えられている。 ```ruby <input name="utf8" type="hidden" value="&#x2713;" /> <input name="authenticity_token" type="hidden" value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" /> ``` このコードは、正しい文字コードを送信できたり、攻撃阻止するために信頼できるトークンを含めたりしている。 このように埋め込みRubyで超便利にコードが書ける。また、セキュリティのコードも生成してくれる。   ## 演習 1.Learn Enough HTML to Be DangerousではHTMLをすべて手動で書き起こしていますが、なぜformタグを使わなかったのでしょうか? 理由を考えてみてください。 A. formタグってのは入力・送信フォームを作成する時に使うタグでであり、 Learn Enough HTML to Be Dangerousの中では入力・送信フォームを作成していないから。 単純に扱っていない。   ## ユーザ登録失敗 エラー一覧を表示する。 ## 正しいフォーム まずは、ユーザ登録の失敗に対応できるcreateアクションを追加。 **app/controllers/users_controller.rb** ```ruby class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new @user = User.new end def create @user = User.new(params[:user]) # 実装は終わっていないことに注意! if @user.save # 保存の成功をここで扱う。 else render 'new' end end end ``` ここで定義した **@user = User.new(params[:user])** は、 ```bash @user = User.new(name: "Foo Bar", email: "foo@invalid", password: "foo", password_confirmation: "bar") ``` と同じ意味になる。 しかしこれでは、脆弱性がある。   ## Strong Parameters paramsハッシュ全体を初期化するのはセキュリティ的に問題が発生する。   解決法 **app/controllers/users_controller.rb** ```ruby def create @user = User.new(user_params) if @user.save # 保存の成功をここで扱う。 else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end ``` このように、 **private** キーワードというものを使って、外部から使えないメソッドを定義し、@userに代入する仕組み。 これで解決   ## 演習 1./signup?admin=1 にアクセスし、paramsの中にadmin属性が含まれていることをデバッグ情報から確認してみましょう。 A. **http://localhost:3000//signup?admin=1** ```bash --- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess admin: '1' controller: users action: new permitted: false ```   ## エラーメッセージ エラーメッセージのパーシャルを作っていく。 まず、 **app/views/users/new.html.erb** にrenderとか、boot-strapが機能するように クラス名も定義していく。 **app/views/users/new.html.erb** ```ruby <% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_for(@user) do |f| %> <%= render 'shared/error_messages' %> <%= f.label :name %> <%= f.text_field :name, class: 'form-control' %> <%= f.label :email %> <%= f.email_field :email, class: 'form-control' %> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> <%= f.submit "Create my account", class: "btn btn-primary" %> <% end %> </div> </div> ``` 次に、パーシャルを作る。今回はディレクトリも生成する。 ```bash $ mkdir app/views/shared $ touch app/views/shared/_error_messages.html.erb ``` **app/views/shared/_error_messages.html.erb** ```html <% if @user.errors.any? %> <div id="error_explanation"> <div class="alert alert-danger"> The form contains <%= pluralize(@user.errors.count, "error") %>. </div> <ul> <% @user.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> ``` **any?** メソッドは、エラーが一つでもあれば発動する。empty?の逆。 **pluralize** は、第一引数によって、単数形か複数形にいてくれる。 また、CSSも追加する。 **app/assets/stylesheets/custom.scss** ```css #error_explanation { color: red; ul { color: red; margin: 0 0 30px 0; } } .field_with_errors { @extend .has-error; .form-control { color: $state-danger-text; } } ``` ここでは、 Sassの@extend関数を使ってBootstrapのhas-errorというCSSクラスを適用している。 ここについて調べる。   ## 演習 1.最小文字数を5に変更すると、エラーメッセージも自動的に更新されることを確かめてみましょう。 A. **app/models/user.rb** ```ruby validates :password, presence: true, length: { minimum: 5 } ``` にする。エラーメッセージも5になる。   2.未送信のユーザー登録フォーム (図 7.12) のURLと、送信済みのユーザー登録フォーム (図 7.18) のURLを比べてみましょう。なぜURLは違っているのでしょうか? 考えてみてください。 A. ここ自信がないが、 **app/views/users/new.html.erb** をブラウザに変更しtら時、formタグのアクションが **"/users"** となるため。 ```html <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post"> ```   ## 失敗時のテスト 統合テストを生成して、登録フォームをテストする。 まず、統合テストを生成する。 ```bash rails generate integration_test users_signup ``` そこに、無効なデータを入れたとき、ユーザの数が変わらないかどうか、つまり変なデータができないかどうかのテスト **test/integration/users_signup_test.rb** ```ruby require 'test_helper' class UsersSignupTest < ActionDispatch::IntegrationTest test "invalid signup information" do get signup_path assert_no_difference 'User.count' do post users_path, params: { user: { name: "", email: "user@invalid", password: "foo", password_confirmation: "bar" } } end assert_template 'users/new' end end ``` テストはGREENになる。   ## 演習 1.リスト 7.20で実装したエラーメッセージに対するテストを書いてみてください。どのくらい細かくテストするかはお任せします。リスト 7.25にテンプレートを用意しておいたので、参考にしてください。 A. **test/integration/users_signup_test.rb** ```ruby require 'test_helper' class UsersSignupTest < ActionDispatch::IntegrationTest test "invalid signup information" do get signup_path assert_no_difference 'User.count' do post users_path, params: { user: { name: "", email: "user@invalid", password: "foo", password_confirmation: "bar" } } end assert_template 'users/new' assert_select 'div#error_explanation' assert_select 'div.alert' end end ``` CSSのクラス、idについてのテストを書いた。   2.ユーザー登録フォームのURLは /signup ですが、無効なユーザー登録データを送付するとURLが /users に変わってしまいます。これはリスト 5.43で追加した名前付きルート (/signup) と、RESTfulなルーティング (リスト 7.3) のデフォルト設定との差異によって生じた結果です。リスト 7.26とリスト 7.27の内容を参考に、この問題を解決してみてください。うまくいけばどちらのURLも /signup になるはずです。あれ、でもテストは greenのままになっていますね...、なぜでしょうか? (考えてみてください) A. それぞれをコピペする。テストでは、ユーザ登録数の差異で判断してるから?   3.リスト 7.25のpost部分を変更して、先ほどの演習課題で作った新しいURL (/signup) に合わせてみましょう。また、テストが greenのままになっている点も確認してください。 A. **test/integration/users_signup_test.rb** ```ruby require 'test_helper' class UsersSignupTest < ActionDispatch::IntegrationTest test "invalid signup information" do get signup_path assert_no_difference 'User.count' do post signup_path, params: { user: { name: "", email: "user@invalid", password: "foo", password_confirmation: "bar" } } end assert_template 'users/new' assert_select 'div#error_explanation' assert_select 'div.alert' end end ```   4.リスト 7.27のフォームを以前の状態 (リスト 7.20) に戻してみて、テストがやはり greenになっていることを確認してください。これは問題です! なぜなら、現在postが送信されているURLは正しくないのですから。assert_selectを使ったテストをリスト 7.25に追加し、このバグを検知できるようにしてみましょう (テストを追加して redになれば成功です)。その後、変更後のフォーム (リスト 7.27) に戻してみて、テストが green になることを確認してみましょう。ヒント: フォームから送信してテストするのではなく、'form[action="/signup"]'という部分が存在するかどうかに着目してテストしてみましょう。 A. コピペし、統合テストに以下を追加。 **est/integration/users_signup_test.rb** ```ruby require 'test_helper' class UsersSignupTest < ActionDispatch::IntegrationTest test "invalid signup information" do get signup_path assert_no_difference 'User.count' do post signup_path, params: { user: { name: "", email: "user@invalid", password: "foo", password_confirmation: "bar" } } end assert_template 'users/new' assert_select 'div#error_explanation' assert_select 'div.alert' assert_select 'form[action="/signup"]' end end ``` アクションが存在しないのでREDになる。   ## ユーザー登録成功 Railsではcreateアクションに対応するビューがないため、慣習的にリダイレクトするようにしている。 **app/controllers/users_controller.rb** ```ruby class UsersController < ApplicationController . . . def create @user = User.new(user_params) if @user.save redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end ``` このようになる。 ここでのリダイレクトコードは ```ruby redirect_to user_url(@user) ``` これと同じ意味で、これの方が分かりやすいが省略された。   ## 演習 1.有効な情報を送信し、ユーザーが実際に作成されたことを、Railsコンソールを使って確認してみましょう。 A. signupしてrails cで確認したらできていた。    2.リスト 7.28を更新し、redirect_to user_url(@user)とredirect_to @userが同じ結果になることを確認してみましょう。 A. 省略。   ## flash フラッシュメッセージを追加していく。 **app/controllers/users_controller.rb** ```ruby class UsersController < ApplicationController . . . def create @user = User.new(user_params) if @user.save flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end ``` 次に、レイアウトにflashを追加。 **app/views/layouts/application.html.erb** ```ruby <% flash.each do |message_type, message| %> <div class="alert alert-<%= message_type %>"><%= message %></div> <% end %> ```   ## 演習 1.コンソールに移り、文字列内の式展開 (4.2.2) でシンボルを呼び出してみましょう。例えば"#{:success}"といったコードを実行すると、どんな値が返ってきますか? 確認してみてください。 A. rails cにて ```bash puts "#{:success}" success ```   2.先ほどの演習で試した結果を参考に、リスト 7.30のflashはどのような結果になるか考えてみてください。 A. rails cにて ```bash "#{flash[:success]}" => "It worked!" ```   ## 実際にユーザ登録 実際に登録してみる。その際、データベースを一旦リセットする。 ```bash rails db:migrate:reset ``` また、サーバも再起動させる。   ## 演習 1.Railsコンソールを使って、新しいユーザーが本当に作成されたのかもう一度チェックしてみましょう。結果は、リスト 7.32のようになるはずです。 A. 省略   2.自分のメールアドレスでユーザー登録を試してみましょう。既にGravatarに登録している場合、適切な画像が表示されているか確認してみてください。 A. 省略   ## 成功時のテスト ユーザが登録成功したときの統合テストを書く。 以下のようになる。 **test/integration/users_signup_test.rb** ```ruby require 'test_helper' class UsersSignupTest < ActionDispatch::IntegrationTest . . . test "valid signup information" do get signup_path assert_difference 'User.count', 1 do post users_path, params: { user: { name: "Example User", email: "user@example.com", password: "password", password_confirmation: "password" } } end follow_redirect! assert_template 'users/show' end end ``` ここでは、User.countでユーザの数を比較しながら、 follow_redirect!でしっかり'users/show'へ移動できたかをテストしている。   ## 演習 1.7.4.2で実装したflashに対するテストを書いてみてください。どのくらい細かくテストするかはお任せします。リスト 7.34に最小限のテンプレートを用意しておいたので、参考にしてください (FILL_INの部分を適切なコードに置き換えると完成します)。ちなみに、テキストに対するテストは壊れやすいです。文量の少ないflashのキーであっても、それは同じです。筆者の場合、flashが空でないかをテストするだけの場合が多いです。 A. **test/integration/users_signup_test.rb** ```ruby assert_not flash.empty? ``` を追加。   2.本文中でも指摘しましたが、flash用のHTML (リスト 7.31) は読みにくいです。より読みやすくしたリスト 7.35のコードに変更してみましょう。変更が終わったらテストスイートを実行し、正常に動作することを確認してください。なお、このコードでは、Railsのcontent_tagというヘルパーを使っています。 A. コピペ   3.リスト 7.28のリダイレクトの行をコメントアウトすると、テストが失敗することを確認してみましょう。 A. 省略。   4.リスト 7.28で、@user.saveの部分をfalseに置き換えたとしましょう (バグを埋め込んでしまったと仮定してください)。このとき、assert_differenceのテストではどのようにしてこのバグを検知するでしょうか? テストコードを追って考えてみてください A. リダイレクトした際に、本当ならば、ユーザが登録され、User.countが増えるはずなのにできていないから、REDになる。   ## プロのデプロイ まずは、マージしてmasterブランチに移動する。 ## 本番環境でのSSL Secure Sockets Layer(SSL)を使うことによって、ローカルのサーバからネットワークに流れる前に、大事な情報を暗号化してくれる。 本番環境用の設定ファイルであるproduction.rbのコードをたった1行変更するだけでSSLを強制し、httpsによる安全な通信を確立できる。 **config/environments/production.rb** ```ruby Rails.application.configure do . . . # Force all access to the app over SSL, use Strict-Transport-Security, # and use secure cookies. config.force_ssl = true . . . end ``` ## 本番環境用のWebサーバー **config/puma.rb** ```ruby workers Integer(ENV['WEB_CONCURRENCY'] || 2) threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5) threads threads_count, threads_count preload_app! rackup DefaultRackup port ENV['PORT'] || 3000 environment ENV['RACK_ENV'] || 'development' on_worker_boot do # Worker specific setup for Rails 4.1+ # See: https://devcenter.heroku.com/articles/ # deploying-rails-applications-with-the-puma-web-server#on-worker-boot ActiveRecord::Base.establish_connection end ``` 中身は理解しなくて良いらしい。   次に、 Pumaが使うようにProcfileで定義する。また、ルートディレクトリに作成。 **./Procfile** ```ruby web: bundle exec puma -C config/puma.rb ```   ## 本番環境へデプロイ ## 演習 1.ブラウザから本番環境 (Heroku) にアクセスし、SSLの鍵マークがかかっているか、URLがhttpsになっているかどうかを確認してみましょう。 A. 省略。   2.本番環境でユーザーを作成してみましょう。Gravatarの画像は正しく表示されているでしょうか? A. 省略。