Ruby on Rails初心者の学習記録 Part2：モデルについて

# はじめに
Ruby on Rails初心者の学習記録Part2です。
[Part1](https://qiita.com/Yasushi-Mo/items/d24fd4abab2c1333c522)では、Rubyの基本文法やRailsを利用したWebアプリケーションの開発環境構築手順及びルーティングについて学びました。
今回は[「Getting Started with Rails」](https://guides.rubyonrails.org/getting_started.html)の[「**6 MVC and You**」](https://guides.rubyonrails.org/getting_started.html#mvc-and-you)を教材にMVCアーキテクチャの**モデル**を学んでいきたいと思います。

# 1. モデルとは
[「Getting Started with Rails」](https://guides.rubyonrails.org/getting_started.html#mvc-and-you-generating-a-model)によると、モデルとは、**データを表現するRubyのクラス**です。また、モデルは *Active Record* と呼ばれるRailsの機能を通して、データベースとやりとりをします。
ということで、実際にモデルを作成して確かめてみます。

# 2. モデルの作成
以下のコマンドでモデルを作成します。
```
rails generate model Article title:string body:text
```
:::note warn
モデル名は**単数形**にする必要があります。インスタンス化されたモデルは**1つ**のデータレコードを表すためです。
:::
実行後、以下のファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/74cb55d6-5889-0175-2510-23cf4b3189f3.png)

# 3. マイグレーション
次はデータベースのマイグレーション（DBデータを保持したまま、DBの構造変更を行う）を行います。
先ほど作成したファイルの中に`db/migrate/20230111005407_create_articles.rb`というマイグレーションファイルがあります。まずはこの中身を確認します。
```20230111005407_create_articles.rb
class CreateArticles < ActiveRecord::Migration[7.0]
  def change
    create_table :articles do |t|
      t.string :title
      t.text :body

      t.timestamps
    end
  end
end
```
この中の`create_table`では、`article`テーブルの構成を定義します。デフォルトでは、`id`カラムをオートインクリメントの主キーとして追加します。
`create_table`内では、`title`と`body`2つのカラムが定義されています。これらのカラムは、先ほどのモデル作成時のコマンドに含まれているため、定義されています。
それでは、以下のコマンドでマイグレーションを実行します。
```
rails db:migration
```
実行後、テーブルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/1fcd54bc-7e42-bd82-6133-3e539f117288.png)
これによりモデルを利用してテーブルとやりとりができるようになります。

# 4. モデルを利用したテーブルとのやりとり
Railsの *console* という機能を利用して少しモデルを触ってみます。

:::note
consoleは`irb (interactive ruby)`のような対話的なコード環境です。
:::
以下のコマンドでconsoleを起動します。
```
rails console
```
以下のような`irb`プロンプトが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/115df470-fac7-d5da-8345-59f8ef9443cb.png)
このプロンプトで、`Article`オブジェクトを初期化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/83516449-c88d-8dc4-d829-398b04f09f78.png)
この時点では、オブジェクトを初期化しているだけです。**データベースには保存されていません**。このconsole内でのみ利用できます。保存するためには、`save`をコールする必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/55facf0e-f14c-bb0a-22d4-ac853f4ce3e2.png)
上記の出力には、`INSERT INTO "articles" ...`というクエリも表示されています、つまり、先ほど初期化した記事がテーブルに挿入されたことを示しています。
また、`article`オブジェクトを表示させると初期化時に含めていない値も表示されます。`id`、`created_at`、`updated_at`属性が設定されています。これらは保存した際、Railsが実施したものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/deb67b11-a1e6-06b8-0b05-edad42d4bdf2.png)
この記事をデータベースから取得したい場合、モデル上で`find`をコールし、この`id`を引数として渡します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/8631574d-aeac-4d2e-1784-11050009c694.png)
すべての記事を取得したい場合、`all`をコールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/5f207fb3-4282-da3b-179c-4323f3f69e1f.png)
これでMVCのモデルの概要については把握できたので、MVCをつなぎあわせてみます。
# 5. 記事のリスト表示
`app/controllers/articles_controller.rb`を開き、すべての記事をデータベースから取得できるよう`index`に追記します。
```articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end
end
```
コントローラー内のインスタンスの変数は、ビューからもアクセスできます。つまり、`app/views/articles/index.html.erb`内で`@aricles`と記載することにより、参照できます。実際にコードを変更して確認します。
```index.html.erb
<h1>Articles</h1>

<ul>
  <% @articles.each do |article| %>
    <li>
      Title: <%= article.title %>
    </li>
  <% end %>
</ul>
<p>Find me in app/views/articles/index.html.erb</p>
```
:::note
上記のコードはHTMLと *ERB* が混在しています。ERB (Embedded Ruby) とは、ドキュメント内に埋め込まれたRubyのコードを評価するテンプレートシステムのことです。
また、ERBの中にも以下2種類のタグがあります。
・`<% %>`：囲まれているRubyコードを評価する
・`<%= %>`：囲まれているRubyコードを評価し、値を返す
そのため、画面上には、`<%= article.title %>`のみ表示されます。
:::
それでは、http://localhost:3000/ にアクセスして確認します。
4. で挿入した記事のタイトルを表示できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/e815b079-cca7-10e5-3e7e-db343f98f572.png)
一連の流れを図にすると、こんな感じになると思います。
（MVCについては、[「RailsにおけるMVC(モデル/ビュー/コントローラ)」](https://www.javadrive.jp/rails/ini/index7.html)の説明がわかりやすかったです。）
```mermaid
sequenceDiagram
    Browser->>Controller: GET http://localhost:3000
    Controller->>Model: all articles
    Model->>DB: all articles
    DB-->>Model: all articles
    Model-->>Controller: all articles
    Controller->>View: all articles
    View-->>Controller: HTML
    Controller-->>Browser: HTML 
```

# 最後に
今回はMVCアーキテクチャのモデルについて学びました。教材にした[「Getting Started with Rails」](https://guides.rubyonrails.org/getting_started.html)は説明が丁寧でとてもわかりやすく、つまることなく進めることができました。
次は[「Getting Started with Rails」](https://guides.rubyonrails.org/getting_started.html)の[「**7 CRUDit Where CRUDit Is Due**」](https://guides.rubyonrails.org/getting_started.html#crudit-where-crudit-is-due)を教材にして、**CRUD**を試したいと思います。

最後までお読みいただきありがとうございました！

- [Part1](https://qiita.com/Yasushi-Mo/items/d24fd4abab2c1333c522)
- [Part3：CRUD（前編）](https://qiita.com/Yasushi-Mo/items/931cfcef990647f1da18)
- [Part4：CRUD（後編）](https://qiita.com/Yasushi-Mo/items/337d5e31e0ea1f56485f)
- [Part5：復習])(https://qiita.com/Yasushi-Mo/items/032b671eed16acdadc6b)

# 参考
- [Getting Started with Rails](https://guides.rubyonrails.org/getting_started.html)
- [RailsにおけるMVC(モデル/ビュー/コントローラ)](https://www.javadrive.jp/rails/ini/index7.html)