質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1318閲覧

Railsチュートリアル12章 パスワードの再設定をテストする でテンプレートエラーが起こる

aiandrox

総合スコア52

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2019/12/05 05:54

編集2019/12/08 01:10

Railsチュートリアル12.3.3でパスワード再設定のテストを書いたのですが、通りませんでした。
原因を調べてみましたが手詰まりになったので質問させていただきます。
どうかよろしくお願いいたします。

エラーメッセージ

Running via Spring preloader in process 45795 Started with run options --seed 49439 FAIL["test_password_resets", Minitest::Result, 4.519563999958336] test_password_resets#Minitest::Result (4.52s) expecting <"password_resets/edit"> but rendering with <[]> test/integration/password_reset_test.rb:37:in `block in <class:PasswordResetTest>' 46/46: [=================] 100% Time: 00:00:04, Time: 00:00:04 Finished in 4.52010s 46 tests, 212 assertions, 1 failures, 0 errors, 0 skips

password_reset_test.rb

require 'test_helper' class PasswordResetTest < ActionDispatch::IntegrationTest def setup @user = users(:michael) ActionMailer::Base.deliveries.clear end test "password resets" do get new_password_reset_path assert_template 'password_resets/new' # メールアドレスが無効 post password_resets_path, params: { password_reset: { email: "" } } assert_not flash.empty? assert_template 'password_resets/new' # メールアドレスが有効 post password_resets_path, params: { password_reset: { email: @user.email } } assert_not_equal @user.reset_digest, @user.reload.reset_digest assert_equal 1, ActionMailer::Base.deliveries.size assert_not flash.empty? assert_redirected_to root_url # パスワード再設定フォーム user = assigns(:user) # メールアドレスが無効 get edit_password_reset_path(user.reset_token, email: '') assert_redirected_to root_url # 無効なユーザー user.toggle!(:activated) get edit_password_reset_path(user.reset_token, email: user.email) assert_redirected_to root_url user.toggle!(:activated) # メールアドレスが有効でトークンが無効 get edit_password_reset_path('wrong token', email: user.email) assert_redirected_to root_url # メールアドレスもトークンも有効 get edit_password_reset_path(user.reset_token, email: user.email) assert_template 'password_resets/edit' # ここでエラーが起きます assert_select "input[name=email][type=hidden][value=?]", user.email # パスワードと確認用パスワードが不一致 patch password_reset_path(user.reset_token), params: { email: user.email, user: {password: 'foobaz', password_confirmation: 'barquux' } } assert_select 'div#error_explanation' # パスワードが空 patch password_reset_path(user.reset_token), params: { email: user.email, user: {password: '', password_confirmation: '' } } assert_select 'div#error_explanation' # 有効なパスワードと確認用パスワード patch password_reset_path(user.reset_token), params: { email: user.email, user: {password: 'foobaz', password_confirmation: 'foobaz' } } assert is_logged_in? assert_not flash.empty? assert_redirected_to user end end

確認したこと

・getの前にdebuggerを入れてuser.reset_tokenを確認したところちゃんと生成されていました。user.emailも"michael@example.com"になっています。
・app/views/password_resets/edit.html.slimは存在します。
・12.3.2の演習まではできているので、開発環境における動作には問題がないと思われます。

ソースコード

routes.rb

Rails.application.routes.draw do root 'static_pages#home' get '/help', to: 'static_pages#help' get '/about', to: 'static_pages#about' get '/contact', to: 'static_pages#contact' get '/signup', to: 'users#new' post '/signup', to: 'users#create' get '/login', to: 'sessions#new' post '/login', to: 'sessions#create' delete 'logout', to: 'sessions#destroy' resources :users resources :account_activations, only: [:edit] resources :password_resets, only: %i[new create edit update] end

password_resets_controller.rb

class PasswordResetsController < ApplicationController before_action :get_user, only: [:edit, :update] before_action :valid_user, only: [:edit, :update] before_action :check_expiration, only: [:edit, :update] def new end def create @user = User.find_by(email: params[:password_reset][:email].downcase) if @user @user.create_reset_digest @user.send_password_reset_email flash[:info] = "Email sent with password reset instructions" redirect_to root_url else flash[:danger] = "Email address not found" render 'new' end end def edit end def update if params[:user][:password].empty? @user.errors.add(:password, :blank) render 'edit' elsif @user.update_attributes(user_params) log_in @user flash[:success] = "Password has been reset." redirect_to @user else render 'edit' end end private def user_params params.require(:user).permit(:password, :password_confirmation) end def get_user @user = User.find_by(email: params[:email]) end def valid_user unless (@user && @user.activated? && @user.authenticated?(:reset, params[:id])) redirect_to root_url end end def check_expiration unless @user.password_reset_expired? flash[:danger] = "Password reset has expired." redirect_to new_password_reset_url end end end

user_mailer_preview.rb

# Preview all emails at http://localhost:3000/rails/mailers/user_mailer class UserMailerPreview < ActionMailer::Preview # Preview this email at http://localhost:3000/rails/mailers/user_mailer/account_activation def account_activation user = User.first user.activation_token = User.new_token UserMailer.account_activation(user) end # Preview this email at http://localhost:3000/rails/mailers/user_mailer/password_reset def password_reset user = User.first user.reset_token = User.new_token UserMailer.password_reset(user) end end

動作環境

Rails 5.2.3
ruby 2.5.3
Ruby on Railsチュートリアル 第4版

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

password_resets_controller.rb の check_expiration で、
unless @user.password_reset_expired?
となっていますが、これですと「期限切れでない限り」という意味になって、
続くエラー処理を実行してしまいます。
ここは if とすべきかと。

投稿2019/12/11 08:19

SakStar

総合スコア24

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiandrox

2019/12/12 01:32

確認して修正したところ、テストが通りました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問