前提・実現したいこと
Railsチュートリアル第12章 3節「パスワードを再設定する」へ取り組む中で、調べてみても解決できないエラーに遭遇したので質問いたします。
12.3.1.1の演習中に、Railsサーバーのログからパスワードリセット用のメールリンクを探してアクセスしたところ、ルート画面に飛ばされてしまい、パスワードリセットのフォームが表示されない状況です。
teratailの同じエラーを出している記事も試してみましたがうまく行かず、12章や11章までさかのぼってコードをコピペしても状況は変わりませんでした。
発生している問題・エラーメッセージ
####Railsサーバーのログ(再設定用メールのリンクにアクセスしたとき)
Started GET "/password_resets/75n959ghPFmrlJktckBrBg/edit?email=example%40railstutorial.org" for 49.104.15.211 at 2020-02-09 04:57:12 +0000 Cannot render console from 49.104.15.211! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 Processing by PasswordResetsController#edit as HTML Parameters: {"email"=>"example@railstutorial.org", "id"=>"75n959ghPFmrlJktckBrBg"} User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "example@railstutorial.org"], ["LIMIT", 1]] Redirected to https://93bfd3f26b434df4a4e3ab34c29fdd54.vfs.cloud9.us-east-2.amazonaws.com/ Filter chain halted as :valid_user rendered or redirected Completed 302 Found in 78ms (ActiveRecord: 0.8ms) Started GET "/" for 49.104.15.211 at 2020-02-09 04:57:12 +0000 Cannot render console from 49.104.15.211! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 Processing by StaticPagesController#home as HTML Rendering static_pages/home.html.erb within layouts/application Rendered static_pages/home.html.erb within layouts/application (2.8ms) Rendered layouts/_rails_default.html.erb (39.5ms) Rendered layouts/_shim.html.erb (0.4ms) Rendered layouts/_header.html.erb (0.7ms) Rendered layouts/_footer.html.erb (0.4ms) Completed 200 OK in 49ms (Views: 48.5ms | ActiveRecord: 0.0ms)
####12.3.3「パスワードの再設定をテストする」の実行結果
[1] guard(main)> 05:08:07 - INFO - Run all 05:08:07 - INFO - Running: all tests Running via Spring preloader in process 13101 Started with run options --seed 18780 FAIL["test_password_resets", PasswordResetsTest, 1.5618210910006383] test_password_resets#PasswordResetsTest (1.56s) expecting <"password_resets/edit"> but rendering with <[]> test/integration/password_resets_test.rb:40:in `block in <class:PasswordResetsTest>' 45/45: [=======================================================================================] 100% Time: 00:00:01, Time: 00:00:01 Finished in 1.84732s 45 tests, 200 assertions, 1 failures, 0 errors, 0 skips /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/jobs/pry_wrapper.rb:279: warning: method Pry#input_array is deprecated. Use Pry#input_ring instead
該当のソースコード
####PasswordResetsのコントローラー
Ruby
1class PasswordResetsController < ApplicationController 2 3 before_action :get_user, only: [:edit, :update] 4 before_action :valid_user, only: [:edit, :update] 5 before_action :check_expiration, only: [:edit, :update] 6 7 def new 8 end 9 10 def create 11 @user = User.find_by(email: params[:password_reset][:email].downcase) 12 if @user 13 @user.create_reset_digest 14 @user.send_password_reset_email 15 flash[:info] = "Email sent with password reset instructions" 16 redirect_to root_url 17 else 18 flash.now[:danger] = "Email address not found" 19 render 'new' 20 end 21 end 22 23 def edit 24 end 25 26 def update 27 if params[:user][:password].empty? 28 @user.errors.add(:password, :blank) 29 render 'edit' 30 elsif @user.update_attributes(user_params) 31 log_in @user 32 flash[:success] = "Password has been reset." 33 redirect_to @user 34 else 35 render 'edit' 36 end 37 end 38 39 private 40 41 def user_params 42 params.require(:user).permit(:password, :password_confirmation) 43 end 44 45 # beforeフィルター 46 47 def get_user 48 @user = User.find_by(email: params[:email]) 49 end 50 51 # 正しいユーザーかどうかの確認 52 def valid_user 53 unless @user && @user.activated? && 54 @user.authenticated?(:reset, params[:id]) 55 redirect_to root_url 56 end 57 end 58 59 # パスワード再設定の有効期限を確認 60 def check_expiration 61 if @user.password_reset_expired? 62 flash[:danger] = "Password reset has expired." 63 redirect_to new_password_reset_url 64 end 65 end 66end 67
####Userモデル
Ruby
1class User < ApplicationRecord 2 3 #仮想トークン属性 4 attr_accessor :remember_token, :activation_token, :reset_token 5 6 before_save :downcase_email 7 before_create :create_activation_digest 8 9 # バリデーション(正規化も含む) 10 validates :name, presence: true, 11 length: { maximum: 50 } 12 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(.[a-z\d\-]+)*.[a-z]+\z/i 13 validates :email, presence: true, 14 length: { maximum: 255 }, 15 format: { with: VALID_EMAIL_REGEX }, 16 uniqueness: { case_sensitive: false } 17 18 #安全なパスワードの生成と、仮想パスワード属性の作成。 19 has_secure_password 20 validates :password, presence: true, 21 length: { minimum: 6 }, 22 allow_nil: true 23 24 # 渡された文字列をハッシュして値を返す 25 def self.digest(string) 26 cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 27 BCrypt::Engine.cost 28 BCrypt::Password.create(string, cost: cost) 29 end 30 31 # ランダムなトークンを返す。cookiesに使用。 32 def self.new_token 33 SecureRandom.urlsafe_base64 34 end 35 36 # 永続セッションのためにユーザーをデータベースに記憶 37 def remember 38 self.remember_token = User.new_token 39 update_attribute(:remember_digest, User.digest(remember_token)) 40 end 41 42 # 渡されたトークンがダイジェストと一致したらtrue 43 def authenticated?(attribute, token) 44 digest = send("#{attribute}_digest") 45 return false if digest.nil? 46 BCrypt::Password.new(digest).is_password?(token) 47 end 48 49 # 永続セッションを破棄。ログアウト時 50 def forget 51 update_attribute(:remember_digest, nil) 52 end 53 54 # アカウントを有効化 55 def activate 56 update_columns(activated: true, activated_at: Time.zone.now) 57 end 58 59 # 有効化用のメールを送信 60 def send_activation_email 61 UserMailer.account_activation(self).deliver_now 62 end 63 64 # パスワード再設定の属性を設定 65 def create_reset_digest 66 self.reset_token = User.new_token 67 update_columns( reset_digest: User.digest(reset_digest), 68 reset_sent_at: Time.zone.now) 69 end 70 71 # パスワード再設定のメールを送信 72 def send_password_reset_email 73 UserMailer.password_reset(self).deliver_now 74 end 75 76 # パスワード再設定の有効期限が切れている場合はtrue 77 def password_reset_expired? 78 reset_sent_at < 2.hours.ago 79 end 80 81 private 82 83 # emailを全て小文字化 84 def downcase_email 85 self.email.downcase! 86 end 87 88 # 有効化トークンとダイジェストを作成及び代入 89 def create_activation_digest 90 self.activation_token = User.new_token 91 self.activation_digest = User.digest(activation_token) 92 end 93end 94
####パスワードリセットのテスト
Ruby
1require 'test_helper' 2 3class PasswordResetsTest < ActionDispatch::IntegrationTest 4 5 def setup 6 ActionMailer::Base.deliveries.clear 7 @user = users(:michael) 8 end 9 10 test "password resets" do 11 get new_password_reset_path 12 assert_template 'password_resets/new' 13 # メールアドレスが無効 14 post password_resets_path, params: { password_reset: { email: "" } } 15 assert_not flash.empty? 16 assert_template 'password_resets/new' 17 # メールアドレスが有効 18 post password_resets_path, 19 params: { password_reset: { email: @user.email } } 20 assert_not_equal @user.reset_digest, @user.reload.reset_digest 21 assert_equal 1, ActionMailer::Base.deliveries.size 22 assert_not flash.empty? 23 assert_redirected_to root_url 24 25 # 以下、パスワード再設定フォームのテスト 26 user = assigns(:user) 27 # メールアドレスが無効 28 get edit_password_reset_path(user.reset_token, email: "") 29 assert_redirected_to root_url 30 # 無効なユーザー 31 user.toggle!(:activated) 32 get edit_password_reset_path(user.reset_token, email: user.email) 33 assert_redirected_to root_url 34 user.toggle!(:activated) 35 # メールアドレスが有効で、トークンが無効 36 get edit_password_reset_path('wrong token', email: user.email) 37 assert_redirected_to root_url 38 # メールアドレスもトークンも有効 39 get edit_password_reset_path(user.reset_token, email: user.email) 40 assert_template 'password_resets/edit' 41 assert_select "input[name=email][type=hidden][value=?]", user.email 42 # 無効なパスワードとパスワード確認 43 patch password_reset_path(user.reset_token), 44 params: { email: user.email, 45 user: { password: "foobaz", 46 password_confirmation: "barquux" } } 47 assert_select 'div#error_explanation' 48 # パスワードが空 49 patch password_reset_path(user.reset_token), 50 params: { email: user.email, 51 user: { password: "", 52 password_confirmation: "" } } 53 assert_select 'div#error_explanation' 54 # 有効なパスワードとパスワード確認 55 patch password_reset_path(user.reset_token), 56 params: { email: user.email, 57 user: { password: "foobaz", 58 password_confirmation: "foobaz" } } 59 assert is_logged_in? 60 assert_not flash.empty? 61 assert_redirected_to user 62 end 63end 64 65
試したこと
####チュートリアルのコードをコピー&ペースト
####teratailの他記事を実践
https://teratail.com/questions/227521
https://teratail.com/questions/201651?link=qa_related_pc
https://teratail.com/questions/239085
(未解決の同症状記事)
色々試していく中で、valid_user (password_resets_controller の beforeフィルタ)が悪さしているのではないかというところまでは分かったのですが、どう解決したらいいのかが分からずに詰まっております。
ご助言いただければとても嬉しいです。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。