Userモデルができあがったので、いよいよユーザー登録機能を追加しましょう。
HTML フォームを使ってWebアプリケーションに登録情報を送信します。
続いて7.4ではユーザーを新規作成して情報をデータベースに保存します。
ユーザー登録手続きの最後には、作成されたユーザーの新しいプロフィールを表示できるようにするために、ユーザーを表示するためのページを作成し、ユーザー用のRESTアーキテクチャを実装する第一歩を踏み出します。
実装した簡明かつ表現豊かな統合テストに対して、 いくつかのテストを追加していきます。
本章では、有効なメールアドレスを持っている(可能性のある)新規ユーザーを増やしていきます。
第11章では、 メールアドレスが本当に有効であることを確かめるために、アカウントを有効化する機能をサインアップの手順に追加します。
ここから難しくなるらしい。
ユーザーを表示する
この節では、まずユーザーの名前とプロフィール写真を表示するためのページを作成します。
モックアップを示しました 。
ユーザープロフィールページの最終的な目標は、ユーザーのプロフィール写真と基本ユーザーデータ、そしてマイクロポストの一覧を表示することです。
$ git checkout -b sign-up
デバッグとRails環境
この節で作成するプロフィールは、このアプリケーションにおける初めての真に動的なページになります。
ビューそのものは1ページのコードですが、アプリケーションのデータベースから取り出した情報を使って各プロフィールの表示をカスタマイズします。
サンプルアプリケーションに動的なページを追加する準備として、ここでWebサイトのレイアウトにデバッグ情報を追加しましょう。
これにより、ビルトインのdebugメソッドとparams変数を使って、各プロフィールページにデバッグ用の情報が表示されるようになります。
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= render 'layouts/rails_default' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %>
      <!--デバッグ情報はRailsの3つのデフォルト環境のうち、開発環境(development)だけで表示されるようになります-->
    </div>
  </body>
</html>
本番環境に展開したアプリケーションではデバッグ情報を表示したくないので、リスト 7.1には次のコードを記述してあります。
if Rails.env.development?
こうしておくと、デバッグ情報はRailsの3つのデフォルト環境のうち、開発環境(development)だけで表示されるようになります。
特に、Rails.env.development?がtrueになるのは開発環境に限られるため、次の埋め込みRubyは
<%= debug(params) if Rails.env.development? %>
本番アプリケーションやテストで挿入されることはありません。
(テスト環境でデバッグ情報が表示されても直接問題になることはありませんが、よいことではありません。デバッグ情報は開発環境以外で表示させないべきです。)
Railsの3つの環境
Railsにはテスト環境(test)、開発環境(development)、そして本番環境(production)の3つの環境がデフォルトで装備されています。Rails consoleのデフォルトの環境はdevelopmentです。
>> Rails.env
=> "development"
>> Rails.env.development?
=> true
>> Rails.env.test?
=> false
上のように、RailsにはRailsというオブジェクトがあり、それには環境の論理値(boolean)を取るenvという属性があります。
例えば、Rails.env.test?はテスト環境ではtrueを返し、それ以外の環境ではfalseを返します。
テスト環境のデバッグなど、他の環境でconsoleを実行する必要が生じた場合は、環境をパラメータとしてconsoleスクリプトに渡すことができます。
$ rails console test
  Loading test environment
  >> Rails.env
  => "test"
  >> Rails.env.test?
  => true
同様にしてRailsサーバーもデフォルトではdevelopmentが使われますが、次のように他の環境を明示的に実行することもできます。
$ rails server --environment production
アプリケーションを本番環境で実行する場合、本番のデータベースが利用できないとアプリケーションを実行できません。
そのため、rails db:migrateを本番環境で実行して本番データベースを作成します。
$ rails db:migrate RAILS_ENV=production
ところで、サンプルアプリケーションを既にHeroku上にデプロイしている場合は、heroku run rails consoleというコマンドを打つことで、本番環境を確認することができます。
$ heroku run rails console
>> Rails.env
=> "production"
>> Rails.env.production?
=> true
当然ながら、Herokuは本番サイト用のプラットフォームなので、実行されるアプリケーションはすべて本番環境となります。
デバッグ出力をきれいに整形するためにカスタムスタイルシートを追加します。
@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のミックスイン機能(ここではbox_sizing)を使っています。
ミックスイン機能を使うことで、CSSルールのグループをパッケージ化して複数の要素に適用することができます。
例えば次のようなコードは、
.debug_dump {
  .
  .
  .
  @include box_sizing;
}
変換される
.debug_dump {
  .
  .
  .
  -moz-box-sizing:    border-box;
  -webkit-box-sizing: border-box;
  box-sizing:         border-box;
}
これはparamsに含まれている内容で、YAML5 という形式で書かれています。
YAMLは基本的にハッシュであり、コントローラとページのアクションを一意に指定します。
演習
1.ブラウザから /about にアクセスし、デバッグ情報が表示されていることを確認してください。
このページを表示するとき、どのコントローラとアクションが使われていたでしょうか?paramsの内容から確認してみましょう。
--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: static_pages
  action: about
permitted: false
2.Railsコンソールを開き、データベースから最初のユーザー情報を取得し、変数userに格納してください。その後、puts user.attributes.to_yamlを実行すると何が表示されますか? ここで表示された結果と、yメソッドを使ったy user.attributesの実行結果を比較してみましょう。
>> puts user.attributes.to_yaml
---
id: 1
name: Michael Hartl
email: michael@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2021-09-23 05:29:52.333553000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2021-09-27 16:05:45.875904000 Z
  zone: *2
  time: *3
password_digest: "$2a$12$/OOziy.MFqYtCaYCaywaeuEirl5rVGYJKqHKhkroaQZKZDS1tw/M6"
=> nil
>> y user.attributes
---
id: 1
name: Michael Hartl
email: michael@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2021-09-23 05:29:52.333553000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2021-09-27 16:05:45.875904000 Z
  zone: *2
  time: *3
password_digest: "$2a$12$/OOziy.MFqYtCaYCaywaeuEirl5rVGYJKqHKhkroaQZKZDS1tw/M6"
=> nil
