前提・実現したいこと
railsチュートリアル12章リスト 12.18のテストでエラーがでてしまいます。
発生している問題・エラーメッセージ
Error: PasswordResetsTest#test_password_resets: NoMethodError: undefined method `reset_sent_at=' for #<User:0x000056333f04c3b0> Did you mean? reset_token= app/models/user.rb:58:in `create_reset_digest' app/controllers/password_resets_controller.rb:12:in `create' test/integration/password_resets_test.rb:19:in `block in <class:PasswordResetsTest>' ```ここに言語名を入力 Ruby cloud9開発 ### 試したこと 以下のコードを確認。 <app/models/user.rb> ``` class User < ApplicationRecord attr_accessor :remember_token, :activation_token, :reset_token before_save :downcase_email before_create :create_activation_digest validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } has_secure_password validates :password, presence: true, length: { minimum: 6 }, allow_nil: true #渡された文字列のハッシュ値を返す def User.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) end # ランダムなトークンを返す def User.new_token SecureRandom.urlsafe_base64 end # 永続セッションのためにユーザーをデータベースに記憶する def remember self.remember_token = User.new_token update_attribute(:remember_digest, User.digest(remember_token)) end # 渡されたトークンがダイジェストと一致したらtrueを返す def authenticated?(attribute, token) digest = send("#{attribute}_digest") return false if digest.nil? BCrypt::Password.new(digest).is_password?(token) end # ユーザーのログイン情報を破棄する def forget update_attribute(:remember_digest, nil) end # アカウントを有効にする def activate update_attribute(:activated, true) update_attribute(:activated_at, Time.zone.now) end # 有効化用のメールを送信する def send_activation_email UserMailer.account_activation(self).deliver_now end # パスワード再設定の属性を設定する def create_reset_digest self.reset_token = User.new_token update_attribute(:reset_digest, User.digest(reset_token)) update_attribute(:reset_sent_at, Time.zone.now) end # パスワード再設定のメールを送信する def send_password_reset_email UserMailer.password_reset(self).deliver_now end # パスワード再設定の期限が切れている場合はtrueを返す def password_reset_expired? reset_sent_at < 2.hours.ago end private # メールアドレスをすべて小文字にする def downcase_email self.email = email.downcase end # 有効化トークンとダイジェストを作成および代入する def create_activation_digest self.activation_token = User.new_token self.activation_digest = User.digest(activation_token) end end
<app/controllers/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] # (1) への対応 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.now[:danger] = "Email address not found" render 'new' end end def edit end def update if params[:user][:password].empty? # (3) への対応 @user.errors.add(:password, :blank) render 'edit' elsif @user.update(user_params) # (4) への対応 log_in @user flash[:success] = "Password has been reset." redirect_to @user else render 'edit' # (2) への対応 end end private def user_params params.require(:user).permit(:password, :password_confirmation) end # beforeフィルタ 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 if @user.password_reset_expired? flash[:danger] = "Password reset has expired." redirect_to new_password_reset_url end end end
<test/integration/password_resets_test.rb>
require 'test_helper' class PasswordResetsTest < ActionDispatch::IntegrationTest def setup ActionMailer::Base.deliveries.clear @user = users(:michael) end test "password resets" do get new_password_reset_path assert_template 'password_resets/new' assert_select 'input[name=?]', 'password_reset[email]' # メールアドレスが無効 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
<確認したこと>
ネット上にあるチュートリアルのgitをみて間違いなさそうなことを確認しました。
またrails db:migrateを再度実施するも解消せず。
bin/rails db:test:prepare実施するもできず。
わかる方アドバイスいただけると幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。