##ユーザーを登録する
###ユーザーを表示させる
####デバッグ情報を追加する
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
.
.
.
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= yield %>
<!--home.html.erbの内容を代入させる-->
<%= render 'layouts/footer' %>
<%= debug(params) if Rails.env.development? %>
<!--デバック情報を表示させる
if Rails.env.development? 開発環境だけに表示させる-->
</div>
</body>
</html>
####デバックの情報のCSSの表示
app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";
/* mixins, variables, etc. */
$gray-medium-light: #eaeaea;
@mixin box_sizing {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
// 箱のようなデザインにする
.
.
.
/* miscellaneous */
.debug_dump {
clear: both;
float: left;
width: 100%;
margin-top: 45px;
@include box_sizing;
}
####userのurlのルーティングを作成
config/routes.rb
Rails.application.routes.draw do
root 'static_pages#home'
get '/signup', to: 'users#new'
# signupのurlを入力してuser/newのアクションが動き、htmlが表示される。
resources :users
# ユーザー情報を表示するURL(/users/1)を追加するためだけのものではありません
# ユーザーのURLを生成するための多数の名前付きルートと共に、
# アクションが利用できるようになるのです
end
####ユーザー情報を表示するための仮のビュー
app/views/users/show.html.erb
<%= @user.name %>, <%= @user.email %>
####新規作成のためにUserコントローラにcreateをアクション
app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
# @user インスタンス変数
# params[:id]の部分はユーザーidの1に置き換わります。
end
def new
end
end
これでプレビューを表示させたところid=1がないと表示された。
railsconsoleでインスタンスを作成
ubuntu:~/environment/my_app (sign-up) $ rails console
Running via Spring preloader in process 7150
Loading development environment (Rails 6.0.3)
2.6.3 :001 > user = User.create(name: "a", email: "abc@def.com", password: "aaaaaa", password_confirmation: "aaaaaa")
(1.7ms) SELECT sqlite_version(*)
(0.1ms) begin transaction
User Exists? (0.8ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ? [["email", "abc@def.com"], ["LIMIT", 1]]
User Create (10.4ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at", "password_digest") VALUES (?, ?, ?, ?, ?) [["name", "a"], ["email", "abc@def.com"], ["created_at", "2021-11-19 15:38:13.272909"], ["updated_at", "2021-11-19 15:38:13.272909"], ["password_digest", "$2a$12$6Sb5WKzynKizowVEO12B0O0EXo09Se9zI32Q11asV.hV4jRTF0JZC"]]
(6.8ms) commit transaction
=> #<User id: 1, name: "a", email: "abc@def.com", created_at: "2021-11-19 15:38:13", updated_at: "2021-11-19 15:38:13", password_digest: [FILTERED]>
そしたらshowアクションが動いた。
####デバッグを使い、状況を把握する
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/users_controller.rb:4:in `show'
Return value is: nil
[3, 12] in /home/ubuntu/environment/my_app/app/controllers/users_controller.rb
3: def show
4: @user = User.find(params[:id])
5: # @user インスタンス変数
6: # params[:id]の部分はユーザーidの1に置き換わります
7: # Rubyを使ってユーザー名とメールアドレスを表示するにはインスタンス変数であることを前提とする
=> 8: debugger
9: end
10:
11: def new
12: end
####ユーザーの画像を追加する(アイコンのような物)
module UsersHelper
# 引数で与えられたユーザーのGravatar画像を返す
def gravatar_for(user)
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
# メアドをハッシュ化する
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
# grabatar_urlに代入する
image_tag(gravatar_url, alt: user.name, class: "gravatar")
# ユーザーのメアドを元にグラバターの画像を表示させる
end
end
####ユーザー個人の画面
app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
</section>
</aside>
</div>
####ユーザー登録画面
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(model: @user, local: true) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
####ストロングパラメータをつける
app/controllers/users_controller.rb
.
.
.
def create
@user = User.new(user_params) # 実装は終わっていないことに注意!
if @user.save
# 保存の成功をここで扱う。
else
render 'new'
end
end
private
def user_params
# ストロングパラメータ
# 使用制限をつける user属性を使うときに
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end
####エラーメッセージを出すようにする
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>サインイン</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(model: @user, local: true) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<!--class: 'form-control'を入れるとBoostrapがうまく取り扱ってくれる-->
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control'%>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
####そのエラーメッセージの中身
app/views/shared/_error_messages.html.erb
<% if @user.errors.any? %>
<!--インスタンス変数にエラーがあれば-->
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(@user.errors.count, "error") %>.
<!--エラーの数と"error”文字列が表示される-->
</div>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
###エラーメッセージのスタイルを決める
app/assets/stylesheets/custom.scss
.
.
.
#error_explanation {
color: red;
ul {
color: red;
margin: 0 0 30px 0;
}
}
.field_with_errors {
@extend .has-error;
.form-control {
color: $state-danger-text;
}
}
####統合テストで有効でない登録は無効にされることを確認
require 'test_helper'
class UsersSignupTest < ActionDispatch::IntegrationTest
test "invalid signup information" do
get signup_path
# 名前付きルートでsignup_pathに取得
assert_no_difference 'User.count' do
# 有効でないのでデータベースには追加されないことを確認
post users_path, params: { user: { name: "",
email: "user@invalid",
password: "foo",
password_confirmation: "bar" } }
# users#show
# 登録ページに情報を登録
end
assert_template 'users/new'
# また登録ページに戻る
end
end
####サインアップ成功時createメソッドの動き
app/controllers/users_controller.rb
.
.
.
def create
@user = User.new(user_params) # 実装は終わっていないことに注意!
if @user.save
# 保存の成功をここで扱う。
flash[:success] = "ようこそ自作アプリへ成功しました!"
redirect_to @user
# 表示させるユーザーページを
else
render 'new'
end
.
.
.
####サインアップの成功時の画面表示
app/views/layouts/application.html.erb
.
.
.
<body>
<%= render 'layouts/header' %>
<div class="container">
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>"><%= message %></div>
<% end %>
<%= yield %>
<!--home.html.erbの内容を代入させる-->
<%= render 'layouts/footer' %>
<%= debug(params) if Rails.env.development? %>
<!--デバック情報を表示させる
if Rails.env.development? 開発環境だけに表示させる-->
</div>
</body>
####成功時の統合テスト
.
.
.
test "valid signup information" do
get signup_path
# サインアップページへアクセスする
assert_difference 'User.count', 1 do
# ユーザーが一つ追加されたことを確認
post users_path, params: { user: { name: "Example User",
email: "user@example.com",
password: "password",
password_confirmation: "password" } }
# 有効な情報を登録
end
follow_redirect!
# POSTリクエストを送信した結果を見て、指定されたリダイレクト先に移動するメソッド
assert_template 'users/show'
# ユーザーページが表示されているか?
end
end