Rails7で基本のCRUDを体験しよう

## 前提
- ↓前回の記事でHello Worldアプリを作成済みである所から始めます。

https://qiita.com/chiepon115/items/16425b12da54df3369ce

- CRUDを体験することが目的なので、使いやすい機能やデザインは完全無視しています。

## Contorllerの準備
前回では、`users`テーブルのデータを表示するだけの機能としましたが、
追加で登録／更新／削除の機能を追加しようと思います。

いわゆるCRUD機能を実装するイメージです。
- C（Create - 登録）
- R（Read - 参照）
- U（Update - 更新）
- D（Delete - 削除）

🌟おまけ
R（参照）は前回実装済みですが、全件取得しか実装していないため、
今回ついでにキー指定で特定のデータを参照できる機能も実装します

まずは枠だけ作ってみましょう。

```ruby:app/controller/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
  end
  
  def show
  end

  def new
  end

  def create
  end

  def edit
  end

  def update
  end

  def destroy
  end
  
  private
  
  def permit_params
    params.require(:user).permit(:name, :age)
  end
end

```

それぞれ中身を書いていきます。
### show（参照）
```ruby:app/controller/users_controller.rb#show
  def show
    @user = User.find(params[:id])
  end
```
パラメータで受け取ったIDに一致するusersを参照します。


### create（新規作成）
```ruby:app/controller/users_controller.rb#new,create
  def new
    @user = User.new
  end

  def create
    @user = User.new(permit_params)
    @user.save
    redirect_to @user 
  end
```
`new`はUserモデルをnewし、新規登録画面を表示しています。
`create`は実際の登録処理です。パラメータで受け取った内容でusersテーブルへ登録します。
更新後は、show画面へリダイレクトします。

### update（更新）
```ruby:app/controller/users_controller.rb#edit,update
  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    @user.update(permit_params)
    redirect_to @user 
  end
```
`edit`はパラメータで受け取ったIDに一致するデータを取得し、更新画面に表示しています。
`update`が実際の更新処理です。
createと同様にパラメータで受け取った内容でIDに一致するusersデータを更新します。

### delete（削除）
```ruby:app/controller/users_controller.rb#destroy
  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to users_path
  end
```
パラメータで受け取ったIDに一致するデータをdestroy（削除）します。


### ストロングパラメータにする
```ruby:app/controller/users_controller.rb#permit_params
  def permit_params
    params.require(:user).permit(:name, :age)
  end
```
登録／更新処理を行えるよう、パラメータを少し加工します。
`require`でパラメータの内、keyがusersのモデルに存在するかを確認し、取り出します。
`permit`で指定したカラムの保存を許可します。

cf.
https://pikawaka.com/rails/permit


## ルーティングの設定
Contorollerに追加したメソッドを呼び出すために`routes.rb`に同様に追記しましょう。

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :users
end

```
この1行でいいみたいです。（色々書こうとしていました。）
以下Rails公式のリファレンスを参照しました。

https://railsguides.jp/routing.html#crud%E3%80%81verb%E3%80%81%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3

上記1行の記述だけで、各種ルーティング設定が行われるようです。
つまりは、以下の設定がなされています。
| HTTP verb | パス | コントローラ#アクション | 目的 |
|-----------|------------|------------|------------|
| GET | /users | users#index | すべてのユーザの一覧を表示 |
| GET | /photos/new | photos#new | ユーザを作成するためのHTMLフォームを返す |
| POST | /users | users#create | ユーザを1件作成する |
| GET | /users/:id | users#show | 特定のユーザを参照する |
| GET | /photos/:id/edit | photos#edit | ユーザ編集用のHTMLフォームを1つ返す |
| PATCH/PUT | /users/:id | users#update | 特定のユーザを更新する |
| DELETE | /users/:id | phouserstos#destroy | 特定のユーザを削除する |

ふむふむ。

## Viewの準備
今はユーザ一覧を表示するindexのみviewを作っている状態なので、
参照／登録／更新／削除を行うための画面（view）を用意します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/ba043b94-02bf-c8df-75b5-19355238266c.png" width="200">

`/app/views/users`配下に作成します。
```ruby:/app/views/users/show.html.erb
<p>Show Page</p>
<p>
  ID:<%= @user.id %>
  Name:<%= @user.name %>
  Age:<%= @user.age %>
</p>
<%= link_to 'top', users_path %>
```
照会画面です。
パラメータで指定したIDのusersデータを表示します。
下部に一覧画面へのリンクをつけています。

```ruby:/app/views/users/new.html.erb
<p>New Page</p>
<%= form_with model: @user do |form| %>
  <div>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :age %><br>
    <%= form.text_field :age %>
  </div>
  
  <div>
    <%= form.submit %>
  </div>
<% end %>
```
登録画面です。
各入力フォームに入力された値をformとして渡します。
`form.submit`でcreate処理を実施します。

```ruby:/app/views/users/edit.html.erb
<p>Edit Page</p>
<%= form_with model: @user do |form| %>
  <div>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :age %><br>
    <%= form.text_field :age %>
  </div>
  
  <div>
    <%= form.submit %>
  </div>
<% end %>
```
更新画面です。
各入力フォームには、指定IDのusersデータが初期表示されています。
フォームの値を書き換えることで、usersのデータを更新できます。
`form.submit`でupdate処理を実施します。


ついでに、各画面に遷移できるよう、indexも少し整えてリンクを追加しました。
```ruby:/app/views/users/index.html.erb
<p>Index Page</p>
<%= link_to 'new', new_user_path %>

<table>
  <tr>
    <th>ID</th>
    <th>Name</th>
    <th>Age</th>
  </tr>
  <% @users.each do |user| %>
    <tr>
      <td><%= user.id %></td>
      <td><%= user.name %></td>
      <td><%= user.age %></td>
      <td><%= link_to 'show', user_path(user) %></td>
      <td><%= link_to 'edit', edit_user_path(user) %></td>
      <td><%= link_to 'destroy', user_path(user),
        data: {turbo_method: 'delete', turbo_confirm: 'Are you sure?'} %>
      </td>
    </tr>
  <% end %>
</table>
```
登録画面、各データ毎に照会画面、更新画面へのリンクおよび削除リンクを表示させます。


## 実際に動かしてみよう
一気に書きましたが、動作確認をしてみましょう。

### トップ画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/2ff3afd1-61d1-1c48-761e-bafe8c45892e.png" width="550">

適当に入れていたデータを一覧表示しています。
まずは新規登録をするために、`new`リンクを押下します。

### 登録画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/23eff567-5305-0407-cd5e-37ebb8a13a03.png" width="550">

usersテーブルのカラムである`name`と`age`の入力フォームおよびsubmitボタンが設置されています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/2d662ae3-dd60-9998-e565-994559e66133.png" width="550">

NameとAgeを入力して、「Create User」ボタンを押下

### 照会画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/f5a9cdb8-6ecc-fdf1-f7c7-835ebafd7bed.png" width="550">

照会画面へ遷移しました。
登録画面で入力した`takagi` `age`のデータが登録され、表示されています。

`top`でトップ画面へ戻ります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/3fa02d8a-5d36-37b3-a430-9f4854e22df0.png" width="550">

新規登録した`takagi`さんも一覧表示されるようになりました。

### 更新画面
`edit`ボタンを押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/90faef01-e99b-465d-bfec-dcca6d5d70ae.png" width="550">

先ほど登録した`takagi`さんのデータが入力フォームに初期設定されています。
`takagi`さんは今年29歳になっていたのでした。なので修正します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/8a669c8d-c079-ce8b-72e1-ec1ae14352c4.png" width="550">

`Update User`ボタンを押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/b0d82d73-4dcd-0dc0-4110-0321fd089ae3.png" width="550">

無事`29`歳に更新されました。

### 削除
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/12cf8bd8-f812-6a80-f0b7-ccd8a874083f.png" width="550">

`takagi`さんを削除します。`destroy`リンクを押下します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/95b14a33-25e5-e78b-66d5-0c198e3a53ef.png" width="550">

`Are You Sure?`という確認ダイアログが表示されます。
`キャンセル`を押下すると、ダイアログが閉じて、削除されずトップ画面に留まります。
`OK`を押下します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744934/79a0ef20-1bf9-8a66-c4c7-e3fbb8881011.png" width="550">

`takagi`さんが削除されました。

## 最後に
- 今回は、単純な`users`テーブルに対してCRUDを体験しました。
- 関連テーブルを作成して、関連データも一緒に更新、削除などもしたいです。
- 業務でrspec書くのに苦戦しているので、早くそこの学習に辿り着きたいです・・・（テストするコードを今ゴリゴリ仕上げようと思ってます）