###編集の失敗
編集に失敗した場合について扱っていきます。
updateアクションの作成をする
####ユーザーのupdateアクションの初期実装
app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
# データベースからユーザー情報を取り出す
end
def new
@user = User.new
#新しくユーザーオプジェクトを作成する
# オブジェクトの属性をつける
end
def create
@user = User.new(user_params)
# 外部メソッドを使う
if @user.save
# 保存の成功をここで扱う。
log_in @user
# 登録後に自動ログインするため
flash[:success] = "Welcome to the Sample App!"
# 成功時一度だけ表示されるメッセージ
redirect_to @user
# urlを指定して表示する
# 保存成功したらurlを表示する
else
render 'new'
# 保存に成功しなければnewアクションに移動する
# 失敗したらまた戻る
end
end
def edit
@user = User.find(params[:id])
# データベースから探す
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
# 更新に成功した場合を扱う。
else
render 'edit'
end
end
private
#外部から使えないようにする
def user_params
# Usersコントローラの内部でのみ実行される
# Web経由で外部ユーザーにさらされない
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
# paramsとは、フォームなどによって送られてきた情報(パラメータ)
# を取得するメソッドのこと
# requireメソッドで受け取るパラメータ群を、
# permitメソッドで利用可能なパラメータ名を指定します。
# require,permitはセキュリティーの問題らしい。
# requireで:hogeを要求している
# permitで許可されていない
# ストロングパラメータは受け取る値に制限をかけている
# 2つでストロングパラメータらしい
end
end
###演習
1.
編集フォームから有効でないユーザー名やメールアドレス、パスワードを使って送信した場合、編集に失敗することを確認してみましょう。
確認
###編集失敗時のテスト
エラーを検知するための統合テストを書いていきましょう。
####統合テストを生成
ubuntu:~/environment/sample_app (updating-users) $ rails generate integration_test users_edit
Running via Spring preloader in process 6559
invoke test_unit
create test/integration/users_edit_test.rb
####編集の失敗に対するテスト
test/integration/users_edit_test.rb
require 'test_helper'
# test_helper.rbのパラメータ群を指定
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "unsuccessful edit" do
get edit_user_path(@user)
# 編集ページを取得
assert_template 'users/edit'
# 編集ページが表示されているか?d
patch user_path(@user), params: { user: { name: "",
email: "foo@invalid",
password: "foo",
password_confirmation: "bar" } }
# 上書きする
# オプション引数かな?
# HTTP の PATCH リクエストメソッドは、リソースへの部分的な変更を適用
# 編集に用いられやすい
# テストだからrequre,permitを使わなくていいのかな?
assert_template 'users/edit'
end
end
#####テスト
ubuntu:~/environment/sample_app (updating-users) $ rails tRunning via Spring preloader in process 8279
Started with run options --seed 50136
30/30: [============================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.60030s
30 tests, 70 assertions, 0 failures, 0 errors, 0 skips
###演習
1.リスト 10.9のテストに1行追加し、正しい数のエラーメッセージが表示されているかテストしてみましょう。ヒント: 表 5.2で紹介したassert_selectを使ってalertクラスのdivタグを探しだし、「The form contains 4 errors.」というテキストを精査してみましょう。
require 'test_helper'
# test_helper.rbのパラメータ群を指定
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "unsuccessful edit" do
get edit_user_path(@user)
# 編集ページを取得
assert_template 'users/edit'
# 編集ページが表示されているか?d
patch user_path(@user), params: { user: { name: "",
email: "foo@invalid",
password: "foo",
password_confirmation: "bar" } }
# 上書きする
# オプション引数かな?
# HTTP の PATCH リクエストメソッドは、リソースへの部分的な変更を適用
# 編集に用いられやすい
# テストだからrequre,permitを使わなくていいのかな?
assert_template 'users/edit'
assert_select "div", "alert"
end
end
ubuntu:~/environment/sample_app (updating-users) $ rails t
Running via Spring preloader in process 8968
Started with run options --seed 41135
FAIL["test_unsuccessful_edit", #<Minitest::Reporters::Suite:0x0000557d393d0e80 @name="UsersEditTest">, 3.456445838000036]
test_unsuccessful_edit#UsersEditTest (3.46s)
<alert> expected but was
<sample app
Home
Help
Log in>..
Expected 0 to be >= 1.
test/integration/users_edit_test.rb:26:in `block in <class:UsersEditTest>'
30/30: [============================] 100% Time: 00:00:03, Time: 00:00:03
Finished in 3.53432s
30 tests, 71 assertions, 1 failures, 0 errors, 0 skips
わからない。
#####答え
require 'test_helper'
# test_helper.rbのパラメータ群を指定
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "unsuccessful edit" do
get edit_user_path(@user)
# 編集ページを取得
assert_template 'users/edit'
# 編集ページが表示されているか?d
patch user_path(@user), params: { user: { name: "",
email: "foo@invalid",
password: "foo",
password_confirmation: "bar" } }
# 上書きする
# オプション引数かな?
# HTTP の PATCH リクエストメソッドは、リソースへの部分的な変更を適用
# 編集に用いられやすい
# テストだからrequre,permitを使わなくていいのかな?
assert_template 'users/edit'
assert_select "div.alert", "The form contains 4 errors."
# alertクラスのdivを探すことによってエラーのタグを探すことができる。
end
end
これでエラーは起こらなかった。