4日目：Scaffold無しでフォーム作成：ModelとView

内容は、[3日目：ScaffoldなしでのApp作成](https://qiita.com/OriverK/items/c1cbcc7e1a92bfced79f)の続き。
#使用環境
**ホストOS: Windows10 Home**
**仮想環境OS: Ubuntu Bento/Bionic**
Ruby：2.51
Rails:5.2.2
**rails new app scanashi0307 -d mysql**


#モデルを作成
##modelとは
- データベースを操作する。
- app/models下に配置される
- データベースに含まれるテーブル毎に用意され、データの登録・取得・更新・削除などを行う

##model作成コマンド
```:terminal
# rails generate model モデル名 カラム名:データ型 カラム名:データ型 ...
rails generate model User name:string email:string sex:integer age:integer address:integer attendance:integer opinion:text
# string型は文字型、integer型は整数型
```
#DBの操作
##テーブルの作成をする。
```:terminal
rails db:migrate
```
##出来たテーブルをMySQL側で確認してみる。

```sql:mysql
mysql>USE scanashi0307_development;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SHOW TABLES;
+------------------------------------+
| Tables_in_scanashi0307_development |
+------------------------------------+
| ar_internal_metadata               |
| schema_migrations                  |
| users                              |
+------------------------------------+
3 rows in set (0.00 sec)

# usersテーブルが作成されたことが分かる。
```

```sql:mysql
mysql> SHOW CREATE TABLE users;
(ハイフン省略)
| users | CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `sex` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `address` int(11) DEFAULT NULL,
  `attendance` int(11) DEFAULT NULL,
  `opinion` text,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
(以下省略)

# rails g modelsで設定したカラム名が作成されているのが分かる。
```

## データベースにfooさんのレコードを追加してみる
```sql:MySQL
mysql> INSERT INTO `users` (`name`, `email`, `sex`, `age`, `address`, `attendance`, `opinion`, `created_at`, `updated_at`) VALUES ('foo', 'foo@gmail.com', 1, 23, 2, 0, 'foooo', '2017-04-04 04:44:44', '2018-04-04 04:44:44');
Query OK, 1 row affected (0.00 sec)
```
##MySQLの中から、追加されているレコードを確認してみる。
```sql
:mysql
mysql> SELECT * FROM users;
+----+------+---------------+------+------+---------+------------+---------+---------------------+---------------------+
| id | name | email         | sex  | age  | address | attendance | opinion | created_at          | updated_at          |
+----+------+---------------+------+------+---------+------------+---------+---------------------+---------------------+
|  1 | foo  | foo@gmail.com |    1 |   23 |       2 |          0 | foooo   | 2017-04-04 04:44:44 | 2018-04-04 04:44:44 |
+----+------+---------------+------+------+---------+------------+---------+---------------------+---------------------+
```
##rails consoleからレコードを確認
```:cosole
# MySQLの外、Rails Console上でレコード確認
# すべてのレコードを取得
User.all
# 表示結果
irb(main):001:0> User.all
   (0.2ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  User Load (0.3ms)  SELECT  `users`.* FROM `users` LIMIT 11
=> #<ActiveRecord::Relation [#<User id: 1, name: "foo", email: "foo@gmail.com", sex: 1, age: 23, address: 2, attendance: 0, opinion: "foooo", created_at: "2017-04-04 04:44:44", updated_at: "2018-04-04 04:44:44">]>
```
##rails console側から新たにレコードを追加する。
```irb:
irb(main):002:0> user = User.create(name: "taro", email: "val@gmail.com", sex: 0, address: 1, attendance: 1, opinion: 'nothing special')
   (0.1ms)  BEGIN
user.save  User Create (2.6ms)  INSERT INTO `users` (`name`, `email`, `sex`, `address`, `attendance`, `opinion`, `created_at`, `updated_at`) VALUES ('taro', 'val@gmail.com', 0, 1, 1, 'nothing special', '2019-03-07 13:18:53', '2019-03-07 13:18:53')
   (3.8ms)  COMMIT
=> #<User id: 2, name: "taro", email: "val@gmail.com", sex: 0, age: nil, address: 1, attendance: 1, opinion: "nothing special", created_at: "2019-03-07 13:18:53", updated_at: "2019-03-07 13:18:53">
irb(main):003:0> user.save
   (0.5ms)  BEGIN
   (0.2ms)  COMMIT
=> true
#user.saveでDBに保存する
```
##Rails Console上でレコード取得コマンド
```
# レコードの全てのユーザ情報を取得
User.all
# レコードの全てののユーザ情報のうち、最後に追加したものを取得
User.all.last
# 最初に追加したユーザを取得して、データを削除
first_user = User.all.first
first_user.destroy
# ユーザ情報を変更
user = User.all.first       #最初に追加したユーザ情報を取得
user.name = "ichitaro"　    #取得した最初のユーザ情報のうち、nameを"ichitaro"にオーバーライド
user.save　　　　　　　　　　 #ユーザ情報を保存
# 追加されているユーザ数をカウント
User.all.count
# カラムの値がXという条件に合致するユーザ情報を取得
# User.find_by(カラム:値)
(.ex) User.find_by(id:2)
```

##controllerのアクションの整備
```app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
   end
end
```
##viewの整備
```erb:app/view/index.html.erb
 <body>
    <h1>Users</h1>
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Sex</th>
          <th>Age</th>
          <th>Address</th>
          <th>Attendance</th>
          <th>Opinion</th>
          <th colspan="3"></th>
        </tr>
      </thead>

      <tbody>
        <% @users.each do |user| %>
          <tr>
            <td><%= user.name %></td>
            <td><%= user.email %></td>
            <td><%= user.sex %></td>
            <td><%= user.age %></td>
            <td><%= user.address %></td>
            <td><%= user.attendance %></td>
            <td><%= user.opinion %></td>
          </tr>
        <% end %>
      </tbody>
    </table>
  </body>
```
```app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>CebuApp</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```
ルーティングを変更

```app/config/routes.erb
resources :users
```
bashでrails routes実行

```
 Prefix Verb   URI Pattern Controller#Action

                    users GET    /users(.:format)            users#index
                          POST   /users(.:format)            users#create
                 new_user GET    /users/new(.:format)        users#new
                edit_user GET    /users/:id/edit(.:format)   users#edit
                     user GET    /users/:id(.:format)        users#show
                          PATCH  /users/:id(.:format)        users#update
                          PUT    /users/:id(.:format)        users#update
                          DELETE /users/:id(.:format)        users#destroy
(以下省略)
```
次に上にある、「users GET    /users(.:format)  users#index 」を実装
UserControllerの中にshowアクションを作成

```app/controllers/users_controller.rb
class UsersController < ApplicationController
    def index
        @users = User.all
    end
# 下が追加したshowアクション
    def show
    end
end
```
```erb:app/views/users/index.html.erb
# user.nameのラインを下の様に変更
<td><%= link_to user.name, user_path(user.id) %></td>
# <% link_to ("A"."/B") %>
# 上はhtml上で <a href="/B">A</a>に変化する。
```
この時点で`rails s`で立ち上げると
![name-ga-link-ni.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/ac09780d-212e-b0b3-c2e0-393cf99049ab.jpeg)
さらに、fooさんのname部分のリンクにアクセスすると、
![showaction-ga-missing.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/fdd404d4-d4eb-926a-a3fc-b67729dc02af.jpeg)
まだ、showアクションを定義していなかった。
##showアクション
- users_pathはusers#indexへのリンク
- new_user_pathはusers#newへのリンク
- edit_user_pathはusers#editへのリンク
- user_pathはusers#showへのリンク

```app/views/users/show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @user.name %>
</p>

<p>
  <strong>Email:</strong>
  <%= @user.email %>
</p>

<p>
  <strong>Sex:</strong>
  <%= @user.sex %>
</p>

<p>
  <strong>Age:</strong>
  <%= @user.age %>
</p>

<p>
  <strong>Address:</strong>
  <%= @user.address %>
</p>

<p>
  <strong>Attendance:</strong>
  <%= @user.attendance %>
</p>

<p>
  <strong>Opinion:</strong>
  <%= @user.opinion %>
</p>

<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
```
##showアクションの定義
```app/controllers/users_controller.rb
def show
    @user = User.find params[:id]
  end
```
nameリンクにアクセスできるようになった
![showアクション.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/d7f4a8b2-527f-fdbb-5940-6ab40a50be63.jpeg)
しかし、まだeditアクションを定義してないので、editリンクにアクセスしても、『UsersController#edit is missing a template』エラーが出るだろう。(そろそろ、エラーのパターンが見えてくる）
##editアクションの定義
```app/controllers/users_controller.rb
def edit
  @user = User.find(params[:id])
end
```
```erb:app/views/users/edit.html.erb
<%= form_with(model: @user, local: true) do |form| %>
  <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this @user from being saved:</h2>

      <ul>
      <% @user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>

  <div class="field">
    <%= form.label :email %>
    <%= form.text_field :email %>
  </div>

  <div class="field">
    <%= form.label :sex %>
    <%= form.number_field :sex %>
  </div>

  <div class="field">
    <%= form.label :age %>
    <%= form.number_field :age %>
  </div>

  <div class="field">
    <%= form.label :address %>
    <%= form.number_field :address %>
  </div>

  <div class="field">
    <%= form.label :attendance %>
    <%= form.number_field :attendance %>
  </div>

  <div class="field">
    <%= form.label :opinion %>
    <%= form.text_area :opinion %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>
```
ここで、`rails s`すると、
![editacton-make.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/aaaad782-116e-410f-8928-97069b47f8e8.jpeg)
ようやく、editページが表示された。
だが、しかし、updateアクションをまだ定義していないので、updateを押すと
![no-update-aciton-error.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/d94c279b-4a89-0d9a-ad35-9075b21af67b.jpeg)
まだ、先は長い。5日目に続く。。


#追加：2日目を参考にし、表示を触ってみる。
性別の値0or1を男性or女性で表示させる。
```app/models/user.rb
class User < ApplicationRecord
    enum sex: { male: 0 ,female: 1}
end
```
男性、女性で表示されるようになった。だが、editページは、テキスト入力のままだ。
![dansei-josei.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/c002c8da-4d41-e7e1-9d1f-dc95ef0d8bb1.jpeg)
ラジオボタンに変更

```erb:app/views/users/edit.html.erb
<div class"field">
    <%= form.label :sex %>
    <%= form.radio_button :sex, 'male' %>男性
    <%= form.radio_button :sex, 'female' %>女性
</div>
```
![seibetu-radiobutton.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/cd6cbebc-2c61-fa66-157b-90f30ae52be3.jpeg)
同様に、年齢、住所、参加不参加もラジオボタンにしておく。
![性別住所参加をラジオ化.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/1d044efe-e23c-1967-de5c-132f800b42ad.jpeg)

fooさんが『23歳』なのは都合が悪いかったので、0に書き換える。

```:console
# レコードの中から、nameがfooであるユーザ情報を取得
user = User.find_by(name:"foo")
# 取得したユーザ情報のうち、ageを0にオーバーライド
user.age = 0
# ユーザ情報をDBに保存する
user.save
# fooさんの年齢が確認されたか、確認してみる。
User.find_by(name: "foo")
# 結果
<User id: 1, name: "foo", email: "foo@gmail.com", sex: "女性", age: 0, address: "日本以外", attendance: "参加", opinion: "foooo", created_at: "2017-04-04 04:44:44", updated_at: "2019-03-08 00:07:47"
# DB上に格納される性別や住所、参加有無も自然言語で保存されるように編集したのか。
```
## 年齢に、10代、20代、30代のラジオボタンを追加しておく
![全部日本語表記.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/bc21679f-17f7-0fea-fb1f-2741f63e70a5.jpeg)
![エディットも全部ラジオ.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/22d8a59c-35a9-8997-b1bf-7b2a7c5459f2.jpeg)
ブラウザ上のカラム表記を日本語にするにはどうすればいいのだろう、また次に。
<strong> </strong>でした