my programming team created an account activation function like in Michael Hartl's Rails tutorial. Now after a few weeks of coding the function stopped working. So that is the full function:
class AccountActivationsController < ApplicationController
#Dieser Controller ist notwendig, um einen neu registrierten Account via Aktivierungsmail zu aktivieren.
def edit
user = User.find_by(email: params[:email])
if user && !user.activated? && user.authenticated?(:activation, params[:id])
user.activate
log_in user
flash[:success] = "Account aktiviert!"
redirect_to user
else
flash[:danger] = "Ungültiger Aktivierungslink"
redirect_to root_url
end
end
end
We get the danger message coming from the else loop. We tried to break the problem down into pieces and now we know that the condition:
user = User.find_by(email: params[:email])
is not successful.
I would like to have some suggestions, why this activation link:
http://localhost:3000/account_activations/hX1eY83-wcs8VqZcPa0H=
3g/edit?email=3Dsami.khedira%40stud.uni-hannover.de
doesn't give the right information to find the User "[email protected]" in the data base. We can see the user in the data base and the save function before worked. I also looked through an earlier version of the app, where it worked. I don't see any changes in the functions, so maybe something that we added somewhere destroyed the registration, but from my point of view there is nothing missing.
Additionally the password_reset function doesn't work as well.
The create User function from the user controller:
def create
@user = User.new(user_params)
if @user.save
@user.send_activation_email
flash[:info] = "Bitte öffnen Sie Ihr E-Mail Postfach, um den Account zu aktivieren."
redirect_to root_url
else
render 'new'
end
end
Here is how we create the digest:
class User < ApplicationRecord
# Activates an account.
def activate
update_columns(activated: true, activated_at: Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
# Sets the 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
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
private
# Converts email to all lower-case.
def downcase_email
self.email = email.downcase
end
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
Views/User Mailer/Account_activation.html.erb:
<h1>Bachelorarbeitszuordnung</h1>
<p>Sehr geehrter Herr / Sehr geehrte Frau <%= @user.name %>,</p>
<p>
Sie haben sich für die Bachelorarbeit registriert! Klicken Sie auf den untenstehenden Link, um ihren Account zu aktivieren:
</p>
<%= link_to "Aktivieren", edit_account_activation_url(@user.activation_token,
email: @user.email) %>
User Mailer:
class UserMailer < ApplicationMailer
def account_activation(user)
@user = user
mail to: user.email, subject: "Account activation"
end
def password_reset(user)
@user = user
mail to: user.email, subject: "Password reset"
end
end
Application Mailer:
class ApplicationMailer < ActionMailer::Base
default from: "[email protected]"
layout 'mailer'
end
Here is the routes file, I already know by other users, that it is not perfect, but I currently don't know how to improve it. I read the guide on rails routing, but I don't see why my routing is not good:
Rails.application.routes.draw do
resources :deadlines
resources :preferences
resources :institutes
resources :users
resources :admin, to: 'users#admin'
get 'password_resets/new'
get 'password_resets/edit'
root 'static_pages#home'
get '/home', to: 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/matching', to: 'static_pages#matching'
get '/cockpit', to: 'static_pages#cockpit'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/performance_show', to: 'users#performance_show'
get '/performance_update', to: 'users#performance_update'
post 'preferences/create_all', to: 'preferences#create_all'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
# Routes für die Buttons der GAMS Berechnung
post 'read_matching', to: 'static_pages#read_matching'
post 'delete_matching', to: 'static_pages#delete_matching'
post 'optimize', to: 'static_pages#optimize'
# Route für Button zum Löschen aller Studenten
delete 'delete_all', to: 'users#delete_all'
#Route für Page zum Löschen des eigenen Accounts.
get 'delete_account', to: 'users#delete_account'
delete 'delete_account_sure', to: 'users#delete_account_sure'
end
And here is my log. It starts with the registration of the user "Sami Khedira":
Started POST "/users" for 127.0.0.1 at 2018-03-13 17:41:09 +0100
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hbZ8A9CWC60nyXYd3nf6Dv0M+d/ViCp0PJ8AmG/fI5ZvyE+hFBt5n8W54gg9yNqZQTfSuOa8PyUD16a3qoRGsg==", "user"=>{"name"=>"Sami Khedira", "mat_number"=>"1234567", "email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Erstelle meinen Account"}
[1m[35m (1.0ms)[0m [1m[36mbegin transaction[0m
[1m[36mUser Exists (3.0ms)[0m [1m[34mSELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?[0m [["email", "[email protected]"], ["LIMIT", 1]]
[1m[35mSQL (0.8ms)[0m [1m[32mINSERT INTO "users" ("name", "email", "created_at", "updated_at", "password_digest", "activation_digest", "mat_number") VALUES (?, ?, ?, ?, ?, ?, ?)[0m [["name", "Sami Khedira"], ["email", "[email protected]"], ["created_at", "2018-03-13 16:41:10.395281"], ["updated_at", "2018-03-13 16:41:10.395281"], ["password_digest", "$2a$10$2BLl1RzF2SOPB9/S5y.oC.W3vUY64GX9jOtd9EfOhrhs3Wnd7Z0Ky"], ["activation_digest", "$2a$10$MaFRiFb195HRm8AQ14OU.ey5ds5qDvR9nznFLBgClNXM21VqQh0AK"], ["mat_number", 1234567]]
[1m[35m (11.9ms)[0m [1m[36mcommit transaction[0m
Rendering user_mailer/account_activation.html.erb within layouts/mailer
Rendered user_mailer/account_activation.html.erb within layouts/mailer (29.8ms)
Rendering user_mailer/account_activation.text.erb within layouts/mailer
Rendered user_mailer/account_activation.text.erb within layouts/mailer (7.8ms)
UserMailer#account_activation: processed outbound mail in 80.2ms
Sent mail to [email protected] (31.7ms)
Date: Tue, 13 Mar 2018 17:41:11 +0100
From: [email protected]
To: [email protected]
Message-ID: <[email protected]>
Subject: Account activation
Mime-Version: 1.0
Content-Type: multipart/alternative;
boundary="--==_mimepart_5aa7ff279cbd7_3afe126dc74620d2";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_5aa7ff279cbd7_3afe126dc74620d2
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Sehr geehrter Herr Sami Khedira,
Sie haben sich f=C3=BCr die Bachelorarbeit registriert! Klicken Sie auf d=
en untenstehenden Link, um ihren Account zu aktivieren:
<a href=3D"http://localhost:3000/account_activations/hX1eY83-wcs8VqZcPa0H=
3g/edit?email=3Dsami.khedira%40stud.uni-hannover.de">Aktivieren</a>
----==_mimepart_5aa7ff279cbd7_3afe126dc74620d2
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<h1>Bachelorarbeitszuordnung</h1>
<p>Sehr geehrter Herr Sami Khedira,</p>
<p>
Sie haben sich f=C3=BCr die Bachelorarbeit registriert! Klicken Sie auf d=
en untenstehenden Link, um ihren Account zu aktivieren:
</p>
<a href=3D"http://localhost:3000/account_activations/hX1eY83-wcs8VqZcPa0H=
3g/edit?email=3Dsami.khedira%40stud.uni-hannover.de">Aktivieren</a>
</body>
</html>
----==_mimepart_5aa7ff279cbd7_3afe126dc74620d2--
Redirected to http://localhost:3000/
Completed 302 Found in 1972ms (ActiveRecord: 65.1ms)
Started GET "/" for 127.0.0.1 at 2018-03-13 17:41:11 +0100
Processing by StaticPagesController#home as HTML
Rendering static_pages/home.html.erb within layouts/application
Rendered static_pages/home.html.erb within layouts/application (22.8ms)
Rendered layouts/_rails_default.html.erb (604.6ms)
Rendered layouts/_shim.html.erb (0.4ms)
Rendered layouts/_header.html.erb (7.5ms)
Rendered layouts/_footer.html.erb (3.8ms)
Completed 200 OK in 765ms (Views: 755.8ms | ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2018-03-13 17:47:23 +0100
Processing by StaticPagesController#home as HTML
Rendering static_pages/home.html.erb within layouts/application
Rendered static_pages/home.html.erb within layouts/application (965.2ms)
Rendered layouts/_rails_default.html.erb (11813.6ms)
Rendered layouts/_shim.html.erb (66.2ms)
Rendered layouts/_header.html.erb (194.1ms)
Rendered layouts/_footer.html.erb (53.3ms)
Completed 200 OK in 14350ms (Views: 14125.1ms | ActiveRecord: 0.0ms)
Thank you very much!
Edit:
User bkunzi01 recommended me to exchange (email: params[:email]) with params[:user][:email]. That gave me the following error:

Logfile:
Started POST "/users" for 127.0.0.1 at 2018-03-14 02:07:04 +0100
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"6vTYSvvGONUEC7hEP/C/AqEHAeQ+oQToqHQGKuBsM7ozw/N+w11mWnIb1x4Io5CWU/eYpYwncObyWWC+zKY4Jg==", "user"=>{"name"=>"Sami Khedira", "mat_number"=>"12345678", "email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Erstelle meinen Account"}
(0.1ms) begin transaction
User Exists (1.9ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ? [["email", "[email protected]"], ["LIMIT", 1]]
SQL (14.4ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at", "password_digest", "activation_digest", "mat_number") VALUES (?, ?, ?, ?, ?, ?, ?) [["name", "Sami Khedira"], ["email", "[email protected]"], ["created_at", "2018-03-14 01:07:04.901137"], ["updated_at", "2018-03-14 01:07:04.901137"], ["password_digest", "$2a$10$whjEx3oPnLxyNFZomWst4uCAPqweV0jBtN342mlx.sJwAm6A4JD7a"], ["activation_digest", "$2a$10$EG9MOsxQYUJC2//VGj6Iyu1CB7/39NP3mMpv1BjE2QrYx2WeZCM7K"], ["mat_number", 12345678]]
(62.6ms) commit transaction
Rendering user_mailer/account_activation.html.erb within layouts/mailer
Rendered user_mailer/account_activation.html.erb within layouts/mailer (9.2ms)
Rendering user_mailer/account_activation.text.erb within layouts/mailer
Rendered user_mailer/account_activation.text.erb within layouts/mailer (9.3ms)
UserMailer#account_activation: processed outbound mail in 142.7ms
Sent mail to [email protected] (116.4ms)
Date: Wed, 14 Mar 2018 02:07:05 +0100
From: [email protected]
To: [email protected]
Message-ID: <[email protected]>
Subject: Account activation
Mime-Version: 1.0
Content-Type: multipart/alternative;
boundary="--==_mimepart_5aa875b94bfdf_4c5f1f7f0d4257f";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_5aa875b94bfdf_4c5f1f7f0d4257f
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Sehr geehrter Herr Sami Khedira,
Sie haben sich f=C3=BCr die Bachelorarbeit registriert! Klicken Sie auf d=
en untenstehenden Link, um ihren Account zu aktivieren:
<a href=3D"http://localhost:3000/account_activations/WFJAfA0Ed4h-eL13PApg=
ng/edit?email=3Dsamikhedira%40stud.uni-hannover.de">Aktivieren</a>
----==_mimepart_5aa875b94bfdf_4c5f1f7f0d4257f
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<h1>Bachelorarbeitszuordnung</h1>
<p>Sehr geehrter Herr / Sehr geehrte Frau Sami Khedira,</p>
<p>
Sie haben sich f=C3=BCr die Bachelorarbeit registriert! Klicken Sie auf d=
en untenstehenden Link, um ihren Account zu aktivieren:
</p>
<a href=3D"http://localhost:3000/account_activations/WFJAfA0Ed4h-eL13PApg=
ng/edit?email=3Dsamikhedira%40stud.uni-hannover.de">Aktivieren</a>
</body>
</html>
----==_mimepart_5aa875b94bfdf_4c5f1f7f0d4257f--
Redirected to http://localhost:3000/
Completed 302 Found in 1177ms (ActiveRecord: 128.8ms)
Started GET "/" for 127.0.0.1 at 2018-03-14 02:07:05 +0100
Processing by StaticPagesController#home as HTML
Rendering static_pages/home.html.erb within layouts/application
Rendered static_pages/home.html.erb within layouts/application (6.4ms)
Rendered layouts/_rails_default.html.erb (234.4ms)
Rendered layouts/_shim.html.erb (0.6ms)
Rendered layouts/_header.html.erb (12.3ms)
Rendered layouts/_footer.html.erb (1.9ms)
Completed 200 OK in 305ms (Views: 301.8ms | ActiveRecord: 0.0ms)
Started GET "/account_activations/WFJAfA0Ed4h-eL13PApg=ng/edit?email=3Dsamikhedira%40stud.uni-hannover.de" for 127.0.0.1 at 2018-03-14 02:07:44 +0100
Processing by AccountActivationsController#edit as HTML
Parameters: {"email"=>"[email protected]", "id"=>"WFJAfA0Ed4h-eL13PApg=ng"}
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `[]' for nil:NilClass):
app/controllers/account_activations_controller.rb:6:in `edit'
You could convert the email and make it url safe like below. You should be alright as long as you are verifying the uniqueness of all the emails in your database. Hope this helps.
So wherever you are generating your activation link, make the 64bit conversion there so that the new link will now look like:
And now when you are getting your
params[:email]you can simply convert it back like so: