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

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

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

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Ruby

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

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

1回答

1187閲覧

Railsチュートリアル12章 11.29のテストが通らない

ken_asano

総合スコア8

Cloud9

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Ruby

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

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

2クリップ

投稿2020/04/29 13:24

現在、Railsチュートリアルの第12章を進めております。以下のようなエラーメッセージが出てリスト12.19のテストが通りません。

##エラーメッセージ

terminal

1ERROR["test_password_resets", PasswordResetsTest, 0.9276049650002278] 2 test_password_resets#PasswordResetsTest (0.93s) 3NoMethodError: NoMethodError: undefined method `reset_sent_at=' for #<User:0x000000000776da70> 4 Did you mean? reset_token= 5 app/models/user.rb:63:in `create_reset_digest' 6 app/controllers/password_resets_controller.rb:12:in `create' 7 test/integration/password_resets_test.rb:18:in `block in <class:PasswordResetsTest>' 8

##該当するコード

app/models/user.rb

rails

1class User < ApplicationRecord 2 attr_accessor :remember_token,:activation_token,:reset_token 3 before_save :downcase_email 4 before_create :create_activation_digest 5 validates :name, presence: true,length:{maximum:50} 6 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i 7 validates :email, presence: true,length:{maximum:255}, 8 format: { with: VALID_EMAIL_REGEX }, 9 uniqueness: {case_sensitive: false} 10 has_secure_password 11 validates :password, presence: true, length: {minimum: 6},allow_nil:true 12 13 # 渡された文字列のハッシュ値を返す 14 def User.digest(string) 15 cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 16 BCrypt::Engine.cost 17 BCrypt::Password.create(string, cost: cost) 18 end 19 20 def User.new_token 21 SecureRandom.urlsafe_base64 22 end 23 24 def downcase_email 25 self.email = email.downcase 26 end 27 28 def create_activation_digest 29 self.activation_token = User.new_token 30 self.activation_digest = User.digest(activation_token) 31 end 32 33 def remember 34 self.remember_token = User.new_token 35 self.update_attribute(:remember_digest,User.digest(remember_token)) 36 end 37 38 39 def forget 40 self.update_attribute(:remember_digest,nil) 41 end 42 43 # トークンがダイジェストと一致したらtrueを返す 44 def authenticated?(attribute, token) 45 digest = self.send("#{attribute}_digest") 46 return false if digest.nil? 47 BCrypt::Password.new(digest).is_password?(token) 48 end 49 50 def activate 51 update_attribute(:activated, true) 52 update_attribute(:activated_at, Time.zone.now) 53 end 54 55 def send_activation_email 56 UserMailer.account_activation(self).deliver_now 57 end 58 59 # パスワード再設定の属性を設定する 60 def create_reset_digest 61 self.reset_token = User.new_token 62 update_attribute(:reset_digest, User.digest(reset_token)) 63 update_attribute(:reset_sent_at, Time.zone.now) 64 end 65 66 # パスワード再設定のメールを送信する 67 def send_password_reset_email 68 UserMailer.password_reset(self).deliver_now 69 end 70 71 #パスワード再設定の期限が切れていない場合はtrueを返す 72 def password_reset_expired? 73 reset_sent_at < 2.hours.ago 74 end 75 76 private 77 78 def downcase_email 79 self.email = self.email.downcase 80 end 81 82 def create_activation_digest 83 self.activation_token = User.new_token 84 self.activation_digest = User.digest(activation_token) 85 # @user.activation_digest => ハッシュ値 86 end 87 88end

app/controllers/password_resets_controller

rails

1class PasswordResetsController < ApplicationController 2 before_action :get_user, only: [:edit,:update] 3 before_action :valid_user, only: [:edit, :update] 4 before_action :check_expiration, only:[:edit,:update] 5 6 def new 7 end 8 9 def create 10 @user = User.find_by(email: params[:password_reset][:email].downcase) 11 if @user 12 @user.create_reset_digest 13 @user.send_password_reset_email 14 flash[:info] = "Email sent with password reset instructions" 15 redirect_to root_url 16 else 17 flash.now[:danger] = "Email address not found" 18 render 'new' 19 end 20 end 21 22 def edit 23 end 24 25 def update 26 if params[:user][:password].empty? # (3) への対応 27 @user.errors.add(:password, :blank) 28 render 'edit' 29 elsif @user.update_attributes(user_params) # (4) への対応 30 log_in @user 31 flash[:success] = "Password has been reset." 32 redirect_to @user 33 else 34 render 'edit' # (2) への対応 35 end 36 end 37 38 39 private 40 41 def user_params 42 params.require(:user).permit(:password,:password_confirmation) 43 end 44 45 def get_user 46 @user = User.find_by(email:params[:email]) 47 end 48 49 #有効なユーザーかどうか確認する 50 def valid_user 51 unless (@user && @user.activated? && 52 @user.authenticated?(:reset,params[:id])) 53 redirect_to root_url 54 end 55 end 56 57 # トークンが期限切れかどうか確認する 58 def check_expiration 59 if @user.password_reset_expired? 60 flash[:danger] = "Password reset has expired." 61 redirected_to new_password_reset_url 62 end 63 end 64end

test/integration/password_resets_test

rails

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 user = assigns(:user) 26 # メールアドレスが無効 27 get edit_password_reset_path(user.reset_token, email: "") 28 assert_redirected_to root_url 29 # 無効なユーザー 30 user.toggle!(:activated) 31 get edit_password_reset_path(user.reset_token, email: user.email) 32 assert_redirected_to root_url 33 user.toggle!(:activated) 34 # メールアドレスが有効で、トークンが無効 35 get edit_password_reset_path('wrong token', email: user.email) 36 assert_redirected_to root_url 37 # メールアドレスもトークンも有効 38 get edit_password_reset_path(user.reset_token, email: user.email) 39 assert_template 'password_resets/edit' 40 assert_select "input[name=email][type=hidden][value=?]", user.email 41 # 無効なパスワードとパスワード確認 42 patch password_reset_path(user.reset_token), 43 params: { email: user.email, 44 user: { password: "foobaz", 45 password_confirmation: "barquux" } } 46 assert_select 'div#error_explanation' 47 # パスワードが空 48 patch password_reset_path(user.reset_token), 49 params: { email: user.email, 50 user: { password: "", 51 password_confirmation: "" } } 52 assert_select 'div#error_explanation' 53 # 有効なパスワードとパスワード確認 54 patch password_reset_path(user.reset_token), 55 params: { email: user.email, 56 user: { password: "foobaz", 57 password_confirmation: "foobaz" } } 58 assert is_logged_in? 59 assert_not flash.empty? 60 assert_redirected_to user 61 end 62end

##試したこと

Webで公開されている12章が終わった状態のコードと比較しましたが、自分では間違いが見当たりませんでした。また、調べたところUserモデルにreset_sent_atが追加されていないことが原因のようで、rails db:rollbackをしたあとマイグレーションファイルを編集し、rails db:migrateとしましたが同じエラーを吐きました。

rails console → User.column_namesでreset_sent_atがあると確認できたのですがだめのようです・・・。

db/migrate/_add_reset_to_users.rb

class AddResetToUsers < ActiveRecord::Migration[5.1] def change add_column :users, :reset_digest, :string add_column :users, :reset_sent_at, :datetime end end

##環境・バージョン
cloud9
rails '5.1.6'

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

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

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

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

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

guest

回答1

0

ベストアンサー

また、調べたところUserモデルにreset_sent_atが追加されていないことが原因のようで、rails db:rollbackをしたあとマイグレーションファイルを編集し、rails db:migrateとしましたが同じエラーを吐きました。

正しい対処のように思います。

test環境でのdbが更新されていないのかもしれません。
Rails テスティングガイド曰く

既存のマイグレーションに変更が加えられていると、テストデータベースを再構築する必要があります。bin/rails db:test:prepareを実行することで再構築できます。

との事なのでbin/rails db:test:prepareを実行してみるといいと思います。

投稿2020/04/29 23:33

asm

総合スコア15147

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

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

ken_asano

2020/04/30 15:25

asm様のご指摘通り、test環境でのdbが更新されておりませんでした。前回に引き続き今回も回答して下さり本当にありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問