8日目(1)：Scaffoldなしの掲示板作成：まとめ

先週のScaffoldなしのくだりから、6日ほど経ってるので、最初から。（前回との重複分は簡潔に）
[3日目：ScaffoldなしでのApp作成](https://qiita.com/OriverK/items/c1cbcc7e1a92bfced79f)
[4日目：Scaffold無しでフォーム作成：ModelとView](https://qiita.com/OriverK/items/c3cc42eee20219361a1c)

#使用環境
ホストOS: Windows10 Home
仮想環境OS: Ubuntu Bento/Bionic
Ruby：2.51
Rails:5.2.2
rails new scanashi0314 -d mysql

#作成に必要なもの要素
- view(@ /app/views/コントローラ名/
    - viewの中身がブラウザに表示される内容
- controller
    - ページ表示の際、controllerを経由して、viewをブラウザに返す。
    - controllerで設定したactionは、controllerと同じ名前のviewフォルダの中から、
    　actionと同じ名前のhtmlファイルを探してブラウザに返す
- routing
    - ブラウザとcontrollerを繋ぐ。
    
#前準備

```
rails new scanshi0314 -d mysql
# gemfileのminiracerコメントイン
bundle install
# app/cinfig/datavase.ymlのパスワ変更
rails db:create
```

#App作成
##cotroller作成
```:terminal
rails g controller Users
```

##routing設定：ブラウザとcontrollerをつなぐ
```app/config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  get 'users', action: :index, controller: 'users'
end
```
##cotroller編集：modelとviewをつなぐ
```app/controllers/users_controller.rb
class UsersController < ApplicationController
    def index
        render plain: 'Hello'
      end
end
```
##model作成:DB操作用
```:terminal
# rails generate model モデル名 カラム名:データ型 カラム名:データ型 ...
rails generate model User name:string email:string sex:integer age:integer address:integer attendance:integer opinion:text
```
##DBのテーブル作成
```:terminal
rails db:migrate
```
## rails cからレコード追加
```console
(1..10).each do |num|
  if num % 2 == 0
    s = 0
    ad = 0
    at = 0
  else
    s = 1
    ad = 1
    at = 1
  end

  user = User.create(name: "taro-#{num}", email: "val-#{num}@gmail.com", sex: s, address: ad, attendance: at, opinion: "nothing special-#{num}")
  user.save
end
```
##indexのaction定義
```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>
```
```erb: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>
```
##routing変更
```erb:app/config/routes.erb
resources :users
```
#actionを編集していく
##`rails routes`で少し確認
```terminal

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
(以下省略)
```
##showアクション定義
```user_controller.rb
def show
    @user = User.find params[:id]
  end
```
##indexページのshowへのリンク作成
```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>
<td><%= link_to 'Show', user %></td>
```
##showページからのリンク作成
- users_pathはusers#indexへのリンク
- new_user_pathはusers#newへのリンク
- edit_user_pathはusers#editへのリンク
- user_pathはusers#showへのリンク

```erb: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 %>
```
##editアクション定義
```app/controllers/users_controller.rb
def edit
  @user = User.find(params[:id])
end
```
##indexからeditへのリンク
```
<td><%= link_to 'Edit', edit_user_path(user) %></td>
```
##editページ編集
```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 %>
```
##updateアクション定義
```
def update
    @user = User.find params[:id]
    if @user.update(params.require(:user).permit(:name, :email, :sex, :age, :address, :attendance, :opinion))
      respond_to do |format|
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      end
    else
      respond_to do |format|
        format.html { render :edit }
      end
    end
end
```
##destroyアクション定義
```app/controllers/users_controller.rb
 def destroy                                                                                                                                                                                                                                                   
    @user = User.find params[:id]
    @user.destroy
    respond_to do |format|
      format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
    end
  end
```
##indexページからのdestroyへのリンク作成
```erb:app/views/users/index.html.erb
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
```
##newアクション定義
```app/controllers/users_controller.rb
def new
    @user = User.new
  end
```
##newページ編集
```erb:app/views/users/new.html.erb
<h1>New User</h1>
<%= 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 %>

<%= link_to 'Back', users_path %>
```
##indexからnewへのリンク作成
```erb:app/views/users/index.html.erb
<%= link_to 'New User', new_user_path %>
```
##createアクション定義
```app/controllers/users_controller.rb
def create
    @user = User.new(params.require(:user).permit(:name, :email, :sex, :age, :address, :attendance, :opinion))
    if @user.save
      respond_to do |format|
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      end
    else
      respond_to do |format|
        format.html { render :edit }
      end
    end
  end
```
#リファクタリング
>[from wikipedia]
>>リファクタリング (refactoring) とは、コンピュータプログラミングにおいて、プログラムの外部から見た動作を変えずにソースコードの内部構造を整理することである。

##createアクションとupdateアクションの共通化
2アクションに下の共通箇所がある

```app/controllers/users_controller.rb
@user = User.new(params.require(:user).permit(:name, :email, :sex, :age, :address, :attendance, :opinion))
```
リファクタリング後

```app/controllers/users_controller.rb
def create
    @user = User.new(user_params)
    if @user.save
      respond_to do |format|
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      end
    else
      respond_to do |format|
        format.html { render :edit }
      end
    end
  end

  def update
    @user = User.find params[:id]
    if @user.update(user_params)
      respond_to do |format|
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      end
    else
      respond_to do |format|
        format.html { render :edit }
      end
    end
  end

private

def user_params
    params.require(:user).permit(:name, :email, :sex, :age, :address, :attendance, :opinion)
  end
end
```
##show. edit. updata, destroyの共通化
共通部分

```app/controllers/users_controller.rb
@user = User.find params[:id]
```
共通化した結果

```app/controllers/users_controller.rb
# set_user追加
def set_user
      @user = User.find params[:id]
    end

# before_action追加
# show, edit, update, destroyアクションの前に、必ず実行の意
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]
```
##アクションのリファクタリング後（全体）
```app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

    def index
        @users = User.all
    end

    def show
    end

    def edit
    end

    def update
        if @user.update(user_params)
            respond_to do |format|
            format.html { redirect_to @user, notice: 'User was successfully updated.' }
        end
        else
            respond_to do |format|
            format.html { render :edit }
           end
         end
    end

    def destroy                                                                                                                                                                                                                                                   
        @user.destroy
          respond_to do |format|
          format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
      end
    end

    def new
        @user = User.new
    end

    def create
        @user = User.new(user_params)
        if @user.save
           respond_to do |format|
          format.html { redirect_to @user, notice: 'User was successfully updated.' }
          end
          else
            respond_to do |format|
            format.html { render :edit }
            end
          end
    end


    private
      def set_user
      @user = User.find params[:id]
      end

      def user_params
        params.require(:user).permit(:name, :email, :sex, :age, :address, :attendance, :opinion)
      end
end
```
#完
全部出来るようになったが、アクション定義方法やら覚えないと。。
![scanashilast.JPG](https://qiita-image-store.s3.amazonaws.com/0/294402/ab456ea8-52b6-fd9b-0a9e-4ce3d25cfc38.jpeg)