先週のScaffoldなしのくだりから、6日ほど経ってるので、最初から。(前回との重複分は簡潔に)
3日目:ScaffoldなしでのApp作成
4日目:Scaffold無しでフォーム作成:ModelとView
#使用環境
ホスト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作成
rails g controller Users
##routing設定:ブラウザとcontrollerをつなぐ
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をつなぐ
class UsersController < ApplicationController
def index
render plain: 'Hello'
end
end
##model作成:DB操作用
# rails generate model モデル名 カラム名:データ型 カラム名:データ型 ...
rails generate model User name:string email:string sex:integer age:integer address:integer attendance:integer opinion:text
##DBのテーブル作成
rails db:migrate
rails cからレコード追加
(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定義
class UsersController < ApplicationController
def index
@users = User.all
end
end
##view編集
<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>
<!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変更
resources :users
#actionを編集していく
##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
(以下省略)
##showアクション定義
def show
@user = User.find params[:id]
end
##indexページのshowへのリンク作成
# 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へのリンク
<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アクション定義
def edit
@user = User.find(params[:id])
end
##indexからeditへのリンク
<td><%= link_to 'Edit', edit_user_path(user) %></td>
##editページ編集
<%= 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アクション定義
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へのリンク作成
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
##newアクション定義
def new
@user = User.new
end
##newページ編集
<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へのリンク作成
<%= link_to 'New User', new_user_path %>
##createアクション定義
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アクションに下の共通箇所がある
@user = User.new(params.require(:user).permit(:name, :email, :sex, :age, :address, :attendance, :opinion))
リファクタリング後
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の共通化
共通部分
@user = User.find params[:id]
共通化した結果
# 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]
##アクションのリファクタリング後(全体)
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