Railsチュートリアル 第2章 - Toyアプリケーション - Micropostsコントローラ

# 前提

[Railsチュートリアル 第2章 - Toyアプリケーション - Usersコントローラ、Userモデル、index.html.erbビュー](https://qiita.com/rapidliner00/items/92c2fba138bc92f68f81)からの続きです。

ホストは以下の状態であることを前提としています。

```:zsh
>>> pwd
~/docker/rails_tutorial_test/toy_app
```

Rails用のDockerコンテナが実行されており、以下の状態であることを前提としています。

```:bash
# pwd
/var/www/toy_app
```

# scaffoldによるMicropostsリソースの生成

早速scaffoldでMicropostsリソースを生成してみましょう。元となるモデル設計は、以下の図で示すとおりです。

![FSmn2i0W38NXtLFa74xUf8W62MWiUN4glNl5eM_xl-4bU3PVeuVICq13Yirxma5Fe3sfaKIT6zlfCdUeHuARQ3ksm7P9_UqDYRNkqmy0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/63c425c9-7c6f-aff1-42ef-de5b14764db1.png)

結果は以下の通りでした。

```:bash
# rails generate scaffold Micropost content:text user_id:integer
Running via Spring preloader in process 749
      invoke  active_record
      create    db/migrate/20190804000712_create_microposts.rb
      create    app/models/micropost.rb
      invoke    test_unit
      create      test/models/micropost_test.rb
      create      test/fixtures/microposts.yml
      invoke  resource_route
       route    resources :microposts
      invoke  scaffold_controller
      create    app/controllers/microposts_controller.rb
      invoke    erb
      create      app/views/microposts
      create      app/views/microposts/index.html.erb
      create      app/views/microposts/edit.html.erb
      create      app/views/microposts/show.html.erb
      create      app/views/microposts/new.html.erb
      create      app/views/microposts/_form.html.erb
      invoke    test_unit
      create      test/controllers/microposts_controller_test.rb
      invoke    helper
      create      app/helpers/microposts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/microposts/index.json.jbuilder
      create      app/views/microposts/show.json.jbuilder
      create      app/views/microposts/_micropost.json.jbuilder
      invoke  test_unit
      create    test/system/microposts_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/microposts.coffee
      invoke    scss
      create      app/assets/stylesheets/microposts.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.scss
```

特に問題なく完了したようです。幸いにして、Springに関連したエラーは発生しませんでした。

続いて、新しいデータモデルでデータベースを更新します。

```:bash
rails db:migrate
== 20190804000712 CreateMicroposts: migrating =================================
-- create_table(:microposts)
   -> 0.0139s
== 20190804000712 CreateMicroposts: migrated (0.0141s) ========================
```

こちらも特に問題なく完了したようです。

scaffoldジェネレータにより、`config/routes.rb`に対して更新がなされたことも確認できました。以下のdiffは、scaffoldジェネレータが実行される前との差分です。

```diff:config/routes.rb
 Rails.application.routes.draw do
+  resources :microposts
   resources :users
   root 'users#index'
 end
```

# Micropostコントローラの中身

Micropostコントローラそのものの定義は、scaffoldジェネレータにより、`app/controllers/microposts_controller.rb`として生成されました。その内容は以下のとおりです。

```ruby:app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
  before_action :set_micropost, only: [:show, :edit, :update, :destroy]

  # GET /microposts
  # GET /microposts.json
  def index
    @microposts = Micropost.all
  end

  # GET /microposts/1
  # GET /microposts/1.json
  def show
  end

  # GET /microposts/new
  def new
    @micropost = Micropost.new
  end

  # GET /microposts/1/edit
  def edit
  end

  # POST /microposts
  # POST /microposts.json
  def create
    @micropost = Micropost.new(micropost_params)

    respond_to do |format|
      if @micropost.save
        format.html { redirect_to @micropost, notice: 'Micropost was successfully created.' }
        format.json { render :show, status: :created, location: @micropost }
      else
        format.html { render :new }
        format.json { render json: @micropost.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /microposts/1
  # PATCH/PUT /microposts/1.json
  def update
    respond_to do |format|
      if @micropost.update(micropost_params)
        format.html { redirect_to @micropost, notice: 'Micropost was successfully updated.' }
        format.json { render :show, status: :ok, location: @micropost }
      else
        format.html { render :edit }
        format.json { render json: @micropost.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /microposts/1
  # DELETE /microposts/1.json
  def destroy
    @micropost.destroy
    respond_to do |format|
      format.html { redirect_to microposts_url, notice: 'Micropost was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_micropost
      @micropost = Micropost.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def micropost_params
      params.require(:micropost).permit(:content, :user_id)
    end
end
```

> Micropostsコントローラ自体の構造をリスト 2.12に示します。リスト 2.12の内容は、UsersControllerがMicropostsControllerに置き換わっていること以外はリスト 2.7と完全に同一である点に注目してください。これは、RESTアーキテクチャが2つのリソースに同じように反映されていることを示しています。

Railsチュートリアルに記載されていた以上の表記は、確かにそのとおりでした。Micropostsコントローラも、Usersコントローラ同様、RESTアーキテクチャを反映して作られていることがわかります。

# マイクロポストを作成してみる

まずは`rails server`を実行します。

```:bash
# rails server
=> Booting Puma
=> Rails 5.1.6 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.5.1-p57), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
```

`http://localhost:8080/microposts/new`にアクセスします。

<img width="846" alt="スクリーンショット 2019-08-04 14.45.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/fe7cc217-f48e-5750-64b5-abd0085857de.png">

このとき、`rails server`は以下のようなメッセージを返しました。

```
Started GET "/microposts/new" for 172.17.0.1 at 2019-08-04 05:44:24 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#new as HTML
  Rendering microposts/new.html.erb within layouts/application
  Rendered microposts/_form.html.erb (64.9ms)
  Rendered microposts/new.html.erb within layouts/application (93.8ms)
Completed 200 OK in 431ms (Views: 341.3ms | ActiveRecord: 11.2ms)
```

[/users/newの場合](https://qiita.com/rapidliner00/items/0ee78427a41638747be8#usersnew%E3%82%92%E9%96%8B%E3%81%8F)と比べて、`UsersController`が`MicropostsController`に変わり、呼び出されるビューの`users`が`microposts`に変わっただけのようです。

続いて、`user_id`が`1`になるマイクロポストを2つ作成してみました。スクリーンショットは以下です。

<img width="846" alt="スクリーンショット 2019-08-04 14.46.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/3d64d948-d68d-7e08-d5e2-6d7d684036eb.png">

「1つのマイクロポストを作成し、当該マイクロポストがブラウザで表示される」という一連の動作において、`rails server`から返ってくるメッセージは以下のようになります。

```
Started POST "/microposts" for 172.17.0.1 at 2019-08-04 05:46:08 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"略", "micropost"=>{"content"=>"First micropost!", "user_id"=>"1"}, "commit"=>"Create Micropost"}
   (0.2ms)  begin transaction
  SQL (34.2ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "First micropost!"], ["user_id", 1], ["created_at", "2019-08-04 05:46:08.950629"], ["updated_at", "2019-08-04 05:46:08.950629"]]
   (15.2ms)  commit transaction
Redirected to http://localhost:8080/microposts/1
Completed 302 Found in 73ms (ActiveRecord: 49.5ms)


Started GET "/microposts/1" for 172.17.0.1 at 2019-08-04 05:46:09 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#show as HTML
  Parameters: {"id"=>"1"}
  Micropost Load (3.7ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Rendering microposts/show.html.erb within layouts/application
  Rendered microposts/show.html.erb within layouts/application (3.2ms)
Completed 200 OK in 387ms (Views: 322.9ms | ActiveRecord: 3.7ms)
```

HTTPの`POST`リクエストをトリガーとして`MicropostsController#create`が走り、SQLの`INSERT`文が発行される…以上一連の手続きが行われました。最終的にHTTPの`POST`メソッドは`302 FOUND`というステータスコードで正常完了し、その上で、リダイレクト先である`/microposts/1`に対する`GET`リクエストが走っています。

# 演習 - マイクロポストページ

## 1. CSSを知っている読者へ: 新しいマイクロポストを作成し、ブラウザのHTMLインスペクター機能を使って「Micropost was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?

マイクロポスト追加直後の時点で、"User was successfully created."と表示されている部分は、`p#notice`というブロックに含まれています。`notice`というid属性が付与されたp要素ですね。

この時点で`p#notice`に適用されているCSSは、DOMインスペクタによると以下のとおりです。

<img width="850" alt="スクリーンショット 2019-08-04 15.05.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/b63a2eef-f993-e0bf-ad66-a2b6bd428426.png">

```css
#notice {
    color: green;
}
p, ol, ul, td {
    font-family: verdana, arial, helvetica, sans-serif;
    font-size: 13px;
    line-height: 18px;
}
```

ここで[F5]キーを押し、ブラウザをリロードします。

リロード後にDOMインスペクタでHTMLソースを見ると、<p id="notice"></p>という行はありました。しかし、内容は空ですね。リロード後のスクリーンショットは以下です。

<img width="850" alt="スクリーンショット 2019-08-04 15.10.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/424136db-abf5-7c63-86c1-c7852b44e638.png">

上述スクリーンショットの通り、`p#notice`は高さ0ピクセルとしてレンダリングされています。CSSにも、上述`p#notice`に適用するスタイルの定義自体は残っています。

全体として、[ユーザーページの演習における類題](https://qiita.com/rapidliner00/items/0ee78427a41638747be8#1-css%E3%82%92%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E8%AA%AD%E8%80%85%E3%81%B8-%E6%96%B0%E3%81%97%E3%81%84%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AEhtml%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%9A%E3%82%AF%E3%82%BF%E3%83%BC%E6%A9%9F%E8%83%BD%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6user-was-successfully-created%E3%81%AE%E7%AE%87%E6%89%80%E3%82%92%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%82%92%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B%E3%81%A8%E3%81%9D%E3%81%AE%E7%AE%87%E6%89%80%E3%81%AF%E3%81%A9%E3%81%86%E3%81%AA%E3%82%8B%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B)と同様の挙動になります。


## 2. マイクロポストの作成画面で、ContentもUserも空にして作成しようとするどうなるでしょうか?

<img width="850" alt="スクリーンショット 2019-08-04 16.54.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/2f729ea8-8006-9e5e-2bf6-6670227c60ed.png">

「Content」欄にも「User」欄にも何も入力せず、そのまま「Create Micropost」ボタンをクリックします。

<img width="850" alt="スクリーンショット 2019-08-04 16.56.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/f7995e7e-bf82-d18c-5db8-adfb457eeeb0.png">

マイクロポストが正常に作成できた、という画面表示がされています。`rails server`からは、以下のようなメッセージが返ってきました。

```
Started POST "/microposts" for 172.17.0.1 at 2019-08-04 07:55:52 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"略", "micropost"=>{"content"=>"", "user_id"=>""}, "commit"=>"Create Micropost"}
   (0.1ms)  begin transaction
  SQL (19.0ms)  INSERT INTO "microposts" ("content", "created_at", "updated_at") VALUES (?, ?, ?)  [["content", ""], ["created_at", "2019-08-04 07:55:52.905446"], ["updated_at", "2019-08-04 07:55:52.905446"]]
   (15.0ms)  commit transaction
Redirected to http://localhost:8080/microposts/4
Completed 302 Found in 52ms (ActiveRecord: 34.1ms)


Started GET "/microposts/4" for 172.17.0.1 at 2019-08-04 07:55:53 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#show as HTML
  Parameters: {"id"=>"4"}
  Micropost Load (8.9ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
  Rendering microposts/show.html.erb within layouts/application
  Rendered microposts/show.html.erb within layouts/application (1.5ms)
Completed 200 OK in 410ms (Views: 358.7ms | ActiveRecord: 8.9ms)
```

`content`が`""`、`user_id`も`""`という形で`MicropostsController#create`という処理が走り、SQLの`INSERT`文が発行されているようです。

<img width="850" alt="スクリーンショット 2019-08-04 17.02.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/2c2fbff8-76bf-304d-4727-516bf3b77fea.png">

`Content`も`User`も空のマイクロポストが追加された/micropostsは、上記スクリーンショットのような状態になっています。

## 3. 141文字以上の文字列をContentに入力した状態で、マイクロポストを作成しようとするとどうなるでしょうか? (ヒント: WikipediaのRubyの記事にある１段落目がちょうど150文字程度ですが、どうなりますか?)

「Ruby is an interpreted, high-level, general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro "Matz" Matsumoto in Japan.」という、空白文字を含めて159文字の文章でマイクロポストを作成してみます。[en:Ruby (programming language) - Wikipedia](https://en.wikipedia.org/wiki/Ruby_(programming_language))の1段落目の内容です。

<img width="1204" alt="スクリーンショット 2019-08-04 17.06.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/fa4f0497-1e21-e041-5fee-24717cb7d711.png">

マイクロポストが正常に作成できた、という画面表示がされています。`rails server`からは、以下のようなメッセージが返ってきました。

```
Started POST "/microposts" for 172.17.0.1 at 2019-08-04 08:05:55 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"略", "micropost"=>{"content"=>"Ruby is an interpreted, high-level, general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro \"Matz\" Matsumoto in Japan.", "user_id"=>"1"}, "commit"=>"Create Micropost"}
   (0.1ms)  begin transaction
  SQL (26.9ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "Ruby is an interpreted, high-level, general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro \"Matz\" Matsumoto in Japan."], ["user_id", 1], ["created_at", "2019-08-04 08:05:55.286861"], ["updated_at", "2019-08-04 08:05:55.286861"]]
   (15.2ms)  commit transaction
Redirected to http://localhost:8080/microposts/5
Completed 302 Found in 53ms (ActiveRecord: 42.3ms)


Started GET "/microposts/5" for 172.17.0.1 at 2019-08-04 08:05:55 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#show as HTML
  Parameters: {"id"=>"5"}
  Micropost Load (6.6ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."id" = ? LIMIT ?  [["id", 5], ["LIMIT", 1]]
  Rendering microposts/show.html.erb within layouts/application
  Rendered microposts/show.html.erb within layouts/application (8.9ms)
Completed 200 OK in 473ms (Views: 422.6ms | ActiveRecord: 6.6ms)
```

メッセージ内容を見るに、正常に処理が進んでいるようです。

ここまでの処理が終わった時点での/micropostsのスクリーンショットは以下のとおりです。

<img width="1330" alt="スクリーンショット 2019-08-04 17.12.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/5f5022c4-04ce-d24e-66cc-5bc020f0a028.png">

## 4. 上記の演習で作成したマイクロポストを削除してみましょう。 

<img width="1330" alt="スクリーンショット 2019-08-04 17.15.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/a40b1594-c28c-b87b-c57e-db96101e623a.png">

先ほどの演習3.で作成したマイクロポストを削除してみます。

<img width="838" alt="スクリーンショット 2019-08-04 17.18.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/bbff6240-34bb-8c9f-2c60-6844e36d3da5.png">

正常にマイクロポストが削除できたようです。`rails server`からは、以下のようなメッセージが返ってきました。

```
Started DELETE "/microposts/5" for 172.17.0.1 at 2019-08-04 08:17:51 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#destroy as HTML
  Parameters: {"authenticity_token"=>"略", "id"=>"5"}
  Micropost Load (5.5ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."id" = ? LIMIT ?  [["id", 5], ["LIMIT", 1]]
   (0.1ms)  begin transaction
  SQL (21.7ms)  DELETE FROM "microposts" WHERE "microposts"."id" = ?  [["id", 5]]
   (13.2ms)  commit transaction
Redirected to http://localhost:8080/microposts
Completed 302 Found in 60ms (ActiveRecord: 40.5ms)


Started GET "/microposts" for 172.17.0.1 at 2019-08-04 08:17:51 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#index as HTML
  Rendering microposts/index.html.erb within layouts/application
  Micropost Load (3.5ms)  SELECT "microposts".* FROM "microposts"
  Rendered microposts/index.html.erb within layouts/application (21.1ms)
Completed 200 OK in 338ms (Views: 302.3ms | ActiveRecord: 3.5ms)
```

`id`をキーとしたHTTPの`DELETE`リクエストをトリガーとして`MicropostsController#destroy`が走り、SQLの`DELTE`文が発行される…以上一連の手続きが行われました。最終的にHTTPの`DELETE`メソッドは`302 FOUND`というステータスコードで正常完了し、その上で、リダイレクト先である`/microposts`に対する`GET`リクエストが走っています。

# マイクロポストをマイクロにする

マイクロポストに140文字制限を加えてみます。Railsチュートリアルの内容の通り、「`app/models/micropost.rb`を変更し、`length`を制限する」という方法を使います。変更前後の`app/models/micropost.rb`の差分は以下のとおりです。

```diff:app/models/micropost.rb
 class Micropost < ApplicationRecord
+  validates :content, length: { maximum: 140 }
 end
```

この状態で「Ruby is an interpreted, high-level, general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro "Matz" Matsumoto in Japan.」という内容のマイクロポストを行うとどうなるでしょうか。やってみましょう。

<img width="838" alt="スクリーンショット 2019-08-04 17.35.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/457b3dfb-3e45-ed31-442e-ba31c3b9aac3.png">

何やらエラーメッセージが出るようになりました。「マイクロポストが長すぎる（最大140文字）」という意味のメッセージですね。

# 演習 - マイクロポストをマイクロにする

## 1. 先ほど2.3.1.1の演習でやったように、もう一度Contentに141文字以上を入力してみましょう。どのように振る舞いが変わったでしょうか? 

140文字を超える内容のマイクロポストを与えたとき、`rails server`からは、以下のようなメッセージが返ってきました。

```
Started POST "/microposts" for 172.17.0.1 at 2019-08-04 08:35:15 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"略", "micropost"=>{"content"=>"Ruby is an interpreted, high-level, general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro \"Matz\" Matsumoto in Japan.", "user_id"=>"1"}, "commit"=>"Create Micropost"}
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
  Rendering microposts/new.html.erb within layouts/application
  Rendered microposts/_form.html.erb (7.5ms)
  Rendered microposts/new.html.erb within layouts/application (47.1ms)
Completed 200 OK in 410ms (Views: 393.5ms | ActiveRecord: 3.2ms)
```

HTTPの`POST`リクエストにより`MicropostsController#create`が走ります。ここまでは正常なマイクロポストと同じ処理内容です。

この先が正常なマイクロポストとの処理内容の違いです。`begin transaction`の後にSQL文が発行されず、`rollback transaction`されています。その後、`new.html.erb`ビューがレンダリングされています。

## 2. CSSを知っている読者へ: ブラウザのHTMLインスペクター機能を使って、表示されたエラーメッセージを調べてみてください。

エラーメッセージ部分のHTMLは以下のとおりです。`error_explanation`という値のid属性を持つ`div`要素です。

```html
<div id="error_explanation">
  <h2>1 error prohibited this micropost from being saved:</h2>
  <ul>
    <li>Content is too long (maximum is 140 characters)</li>
  </ul>
</div>
```

`error_explanation`値のid属性を持つ要素と、その子要素に対して適用されるCSSは以下のとおりです。

```css
#error_explanation {
    width: 450px;
    border: 2px solid red;
    padding: 7px 7px 0;
    margin-bottom: 20px;
    background-color: #f0f0f0;
}

#error_explanation h2 {
    text-align: left;
    font-weight: bold;
    padding: 5px 5px 5px 15px;
    font-size: 12px;
    margin: -7px -7px 0;
    background-color: #c00;
    color: #fff;
}

#error_explanation ul li {
    font-size: 12px;
    list-style: square;
}
```

# ユーザーはたくさんマイクロポストを持っている

「1人のユーザーに複数のマイクロポストがある」という関係性は、`/app/models/user.rb`を書き換えることによって宣言できます。

```diff:/app/models/user.rb
 class User < ApplicationRecord
+  has_many :microposts
 end
```

「1つのマイクロポストは1人のユーザーにのみ属する」という関係性は、`app/models/micropost.rb`を書き換えることによって宣言できます。

```diff:app/models/micropost.rb
 class Micropost < ApplicationRecord
+  belongs_to :user
   validates :content, length: { maximum: 140 }
 end
```

`rails console`コマンドを使って、ユーザーとマイクロポストの関連付けを確認してみます。

```
# rails console
Running via Spring preloader in process 840
Loading development environment (Rails 5.1.6)
irb(main):001:0> first_user = User.first
  User Load (1.5ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.org", created_at: "2019-07-30 21:10:39", updated_at: "2019-07-31 09:30:00">
irb(main):002:0> first_user.microposts
  Micropost Load (1.7ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ?  [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "First micropost!", user_id: 1, created_at: "2019-08-04 05:46:08", updated_at: "2019-08-04 05:46:08">, #<Micropost id: 2, content: "Second micropost", user_id: 1, created_at: "2019-08-04 05:46:33", updated_at: "2019-08-04 05:46:33">, #<Micropost id: 3, content: "Test", user_id: 1, created_at: "2019-08-04 06:04:03", updated_at: "2019-08-04 06:04:03">]>
irb(main):003:0> micropost = first_user.microposts.first
  Micropost Load (6.1ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."id" ASC LIMIT ?  [["user_id", 1], ["LIMIT", 1]]
=> #<Micropost id: 1, content: "First micropost!", user_id: 1, created_at: "2019-08-04 05:46:08", updated_at: "2019-08-04 05:46:08">
irb(main):004:0> micropost.user
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.org", created_at: "2019-07-30 21:10:39", updated_at: "2019-07-31 09:30:00">
irb(main):005:0> exit
```

# 演習 - ユーザーはたくさんマイクロポストを持っている

## 1. ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示してみましょう。（略）

「ユーザーの最初のマイクロポスト」というと、その内容を表示できるようにすればいいのでしょうか。そのように解釈して進めることとします。

編集対象のファイルは`app/views/users/show.html.erb`ですね。変更内容の差分を以下に示します。

```diff
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index 3816c64..70466c2 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -10,5 +10,10 @@
   <%= @user.email %>
 </p>
 
+<p>
+  <strong>First Micropost:</strong>
+  <%= @user.microposts.first.content %>
+</p>
+
 <%= link_to 'Edit', edit_user_path(@user) %> |
 <%= link_to 'Back', users_path %>
```

First Micropostの内容が表示されるようにしたときの/users/1のスクリーンショットを以下に示します。

<img width="838" alt="スクリーンショット 2019-08-04 18.21.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/0d0c514c-8c0f-c5db-c698-8df090ebb3f7.png">

## 2. [リスト 2.16](https://railstutorial.jp/chapters/toy_app?version=5.1#code-validates_content_presence)は、マイクロポストのContentが存在しているかどうかを検証するバリデーションです。マイクロポストが空でないことを検証できているかどうか、実際に試してみましょう ([図 2.16](https://railstutorial.jp/chapters/toy_app?version=5.1#fig-micropost_content_cant_be_blank)のようになっていると成功です)。 

`app/models/micropost.rb`を書き換えます。変更内容の差分を以下に示します。

```diff
diff --git a/app/models/micropost.rb b/app/models/micropost.rb
index c4a69b3..f7104f5 100644
--- a/app/models/micropost.rb
+++ b/app/models/micropost.rb
@@ -1,4 +1,5 @@
 class Micropost < ApplicationRecord
   belongs_to :user
-  validates :content, length: { maximum: 140 }
+  validates :content, length: { maximum: 140 },
+                      presence: true
 end
```

当該変更を加えた状態で、空のマイクロポストの投稿を試みます。結果は以下のようになりました。

<img width="838" alt="スクリーンショット 2019-08-04 18.29.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/8d733791-829a-ca2f-eb42-e375903ca03a.png">

期待通りの動作をしていますね。`rails server`からは、以下のようなメッセージが返ってきました。

```
Started POST "/microposts" for 172.17.0.1 at 2019-08-04 09:28:59 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"略", "micropost"=>{"content"=>"", "user_id"=>"1"}, "commit"=>"Create Micropost"}
   (0.1ms)  begin transaction
  User Load (1.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
   (0.1ms)  rollback transaction
  Rendering microposts/new.html.erb within layouts/application
  Rendered microposts/_form.html.erb (2.7ms)
  Rendered microposts/new.html.erb within layouts/application (39.2ms)
Completed 200 OK in 602ms (Views: 490.6ms | ActiveRecord: 8.0ms)
```

SQLの`INSERT`文が発行されずに`rollback transaction`となっています。

## 3. [リスト 2.17](https://railstutorial.jp/chapters/toy_app?version=5.1#code-toy_user_presence_valications)のFILL_INとなっている箇所を書き換えて、Userモデルのnameとemailが存在していることを検証してみてください (図 2.17)。

変更するファイルは`app/models/user.rb`です。変更内容のdiffは以下のとおりです。

```diff
diff --git a/app/models/user.rb b/app/models/user.rb
index 6c05c07..b4618de 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,3 +1,5 @@
 class User < ApplicationRecord
   has_many :microposts
+  validates :name, presence: true
+  validates :email, presence: true
 end
```

/users/newにアクセスし、Name欄、Email欄ともに空の状態で「Create User」ボタンをクリックしてみます。

<img width="838" alt="スクリーンショット 2019-08-05 19.29.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/07f19aaf-356b-eee8-9fbb-44b2c1f94d61.png">

エラーにより、ユーザーの生成処理は行われませんでした。期待通りの動作をしていますね。`rails server`からは、以下のようなメッセージが返ってきました。

```
Started POST "/users" for 172.17.0.1 at 2019-08-04 09:39:16 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"略", "user"=>{"name"=>"", "email"=>""}, "commit"=>"Create User"}
   (0.2ms)  begin transaction
   (0.1ms)  rollback transaction
  Rendering users/new.html.erb within layouts/application
  Rendered users/_form.html.erb (4.1ms)
  Rendered users/new.html.erb within layouts/application (29.4ms)
Completed 200 OK in 425ms (Views: 414.5ms | ActiveRecord: 0.3ms)
```

`user`の`name`、`email`ともに空文字列である`Create User`という要求が送信されました。しかし、SQLの`INSERT`文が発行されずに`rollback transaction`となっています。

Userモデルの存在性検証はうまく機能したようです。

# 継承の階層

Usersモデルにおける継承の階層については、[前のエントリで触れました。](https://qiita.com/rapidliner00/items/92c2fba138bc92f68f81#users%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%81%AF)Micropostモデルも、Usersモデル同様に`ApplicationRecord`クラスを継承しています。

```ruby:app/models/micropost.rb
class Micropost < ApplicationRecord
  ...
end
```

`ApplicationRecord`クラスは、`ActiveRecord::Base`というクラスを継承しています。

```ruby:app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end
```

以下はUsersController並びにMicropostsコントローラの定義です。いずれも`ApplicationController`というクラスを継承しています。

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController
  ...
end
```

```ruby:app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
  ...
end
```

`ApplicationController`クラスは、`ActionController::Base`というクラスを継承しています。ActionControllerクラスの詳細を知りたい場合、[Action Controller の概要 - Rails Guides](https://railsguides.jp/action_controller_overview.html)を読んでみるとよいでしょう。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  ...
end
```

# 演習 - 継承の階層

## 1. Applicationコントローラのファイルを開き、`ApplicationController`が`ActionController::Base`を継承している部分のコードを探してみてください。 

上述の通りですね。

## 2.`ApplicationRecord`が`ActiveRecord::Base`を継承しているコードはどこにあるでしょうか? 先ほどの演習を参考に、探してみてください。ヒント: コントローラと本質的には同じ仕組みなので、app/modelsディレクトリ内にあるファイルを調べてみると...?) 

[Usersモデルとは - Railsチュートリアル 第2章 - Toyアプリケーション - Usersコントローラ、Userモデル、index.html.erbビュー](https://qiita.com/rapidliner00/items/92c2fba138bc92f68f81#users%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%81%AF)内で既に言及していました。