I read chapter 12 of the Rails tutorial and deployed it to heroku.
When I sent an existing email address, an error similar to the one shown below occurred.
I can send it in the Rails environment.
For some reason, I can't send what I deployed to heroku.
Looking at the log, it was as follows:
2020-06-19T04:22:54.566364 + 00:00 app [web.1]:F, [2020-06-19T04:22:54.566307#4]FATAL--:[18842aaf-91d3-45d6-be88-85d52aea211f]
2020-06-19T04:22:54.566502 + 00:00 app [web.1]:F, [2020-06-19T04:22:54.566452#4]FATAL --:[18842aaf-91d3-45d6-be88-85d52aea211f] NoMethodError(undefined method`reset_digest='for#<User:0x0000555861fa7030>
2020-06-19T04:22:54.566503 + 00:00 app [web.1]: Did you mean?reset_token=):
2020-06-19T04:22:54.566542 + 00:00 app [web.1]:F, [2020-06-19T04:22:54.566499#4]FATAL --:[18842aaf-91d3-45d6-be88-85d52aea211f]
2020-06-19T04:22:54.566584+00:00 app [web.1]:F, [2020-06-19T04:22:54.566545#4]FATAL --:[18842aaf-91d3-45d6-be88-85d52aea211f] app/models/user.rb:20:in`create_reset_digest'
2020-06-19T04:22:54.566584 + 00:00 app [web.1]: [18842aaf-91d3-45d6-be88-85d52aea211f] app/controllers/password_resets_controller.rb:12:in`create'
2020-06-19T04:22:54.5658553 + 00:00 heroku [router]: at=info method=POST path="/password_resets" host=randomtag.herokuapp.com request_id=18842, aaf-91d3-45d6-be88-85d52aea211f fwd="69.118.84.101" dyno=1 connect=1svice=32
From here, I guessed that the reset_digest method might not exist.
models/user.rb and
controllers/password_resets_controller.rb
could not identify the problem by itself.
I wonder if there is a problem with how to write the following parts.
I feel it, but I haven't been able to find out the cause.
#Set password reset attributes
def create_reset_digest
self.reset_token=User.new_token
update_columns(reset_digest:User.digest(reset_token),reset_sent_at:Time.zone.now)
end
If anyone seems to know the cause,
I would appreciate it if you could advise me.
Development Environment: AWS Cloud 9
production environment:heroku
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]
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
default
end
default update
if params [:user] [:password].empty?
@user.errors.add(:password,:blank)
render 'edit'
[email protected]_attributes(user_params)
log_in@user
@user.update_attribute(:reset_digest,nil)
flash[:success] = "Password has been reset."
redirect_to@user
else
render 'edit'
end
end
private
def user_params
param.require(:user).permit(:password,:password_confirmation)
end
default_user
@user=User.find_by (email:params[:email])
end
# verify the correct user
default_user
unless(@user&@user.activated?&
@user.authenticated?(:reset,params[:id]))
redirect_to root_url
end
end
# check if a token has expired
def check_expiration
[email protected] ssword_reset_expired?
flash [:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
models/user.rb
class User<ApplicationRecord
attr_accessor:remember_token,:activation_token,:reset_token
before_save —downcase_email
before_save {self.email.downcase!}
values:name,presence:true,length:{maximum:50}
values:email, presence:true, length:{maximum:255},
format: {with:/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i},
unity: {case_sensitive:false}
has_secure_password
has_many:hashtags, dependent::destroy
# set password reset attributes
def create_reset_digest
self.reset_token=User.new_token
update_columns(reset_digest:User.digest(reset_token),reset_sent_at:Time.zone.now)
end
# send a password reset e-mail
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
class<<self
# return the hash value of a passed string
def digest (string)
cost=ActiveModel::SecurePassword.min_cost?BCrypt::Engine::MIN_COST:
BCrypt::Engine.cost
BCrypt::Password.create(string, cost:cost)
end
# return a random token
def new_token
SecureRandom.urlsafe_base64
end
end
# Returns true if password reset has expired
def password_reset_expired?
reset_sent_at<2.hours.ago
end
private
# lowercase all e-mail addresses
def downcase_email
self.email=email.downcase
end
# Create and replace activation tokens and digests
def create_activation_digest
self.activation_token=User.new_token
self.activation_digest=User.digest(activation_token)
end
end
update_columns(reset_digest:User.digest(reset_token), reset_sent_at:Time.zone.now)
There seems to be an error here.
Does the reset_digest
column exist in the User table in the database connected by the app in heroku?
© 2024 OneMinuteCode. All rights reserved.