Devise: Pass unconfirmed email address back to sign in page - ruby-on-rails

When a user registers for an account in my Rails app, I'm using the default Devise behavior to send them a confirmation email. On the website, after the user fills out the registration form, they are automatically redirected to the login page with an alert notice that they need to confirm their account via email:
"Please confirm your acount via email."
I would like the alert to be more specific, like
"A confirmation email has been sent to <%= confirmation_email%>.
Please click the link in the email to finish the registration
process!"
How can I pass the unconfirmed email address back to the view?

I imagine that when you're creating the user, you're still saving the unconfirmed email address in your database when you create/save the user? If so, you should be able to call it the same way you call other variables in the view. Make sure they are defined in the associated controller and then call them up in the view with something like <%= #user.email %>.

Needed to override devise registrations controller create action with this code:
class RegistrationsController < Devise::RegistrationsController
# POST /resource
def create
build_resource(sign_up_params)
if resource.save
# this block will be used when user is saved in database
if resource.active_for_authentication?
# this block will be used when user is active or not required to be confirmed
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
# this block will be used when user is required to be confirmed
user_flash_msg if is_navigational_format? #created a custom method to set flash message
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
# this block is used when validation fails
clean_up_passwords resource
respond_with resource
end
end
private
# set custom flash message for unconfirmed user
def user_flash_msg
if resource.inactive_message == :unconfirmed
#check for inactive_message and pass email variable to devise locals message
set_flash_message :notice, :"signed_up_but_unconfirmed", email: resource.email
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}"
end
end
end
Then pass email variable in devise.en.yml file
en:
devise:
registrations:
signed_up_but_unconfirmed: "A confirmation email has been sent to %{email}. Please click the link in the email to finish the registration process!"

Related

on sign up if email already exist then render user on specific page where i can display some message

i just want to send confirmation instructions to user again if email already exist.
Thats what i've implemented, it just let user to sign Up if email is unique. if email already exist it just don't do anything.
class RegistrationsController < Devise::RegistrationsController
layout 'pages'
def new
build_resource
yield resource if block_given?
respond_with resource
end
def create
build_resource(sign_up_params)
admin = User.create(first_name: "")
resource.authenticatable = admin
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: accounts_get_started_path(resource)
end
else
byebug
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
end
def edit
super
end
def update
super
end
def destroy
super
end
end
If the email already exists you should resend devise confirmation mail by doing this:
Devise::Mailer.confirmation_instructions(resource).deliver
You can use valid? runs all the validations within the specified context. Returns true if no errors are found, otherwise it returns false. (Refer to this link for more info.)
NOTE: Here I am assuming you have uniqueness validation on email field. (Refer this link for more info)
If you have validation, then your code looks like
def create
build_resource(sign_up_params)
.
.
if resource.valid?
# your code for saving details
else
# Your code to redirct to different page
redirect_to where_you_want
end
end

Rails 4 + Devise: Send welcome email with password reset instructions

I have my registrations set up such that I create the account for a user with a predetermined password, then I would like to send them a welcome email, with a link to the Devise edit_user_password_url.
My method fails because when the User follows the link, they see the following: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
How can I make my welcome email include the proper link for password reset?
# RegistrationsController
def create
if params[:user] && !params[:user][:password]
params[:user][:password] = "testpassword" #obviously not real
build_resource(sign_up_params)
puts sign_up_params
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
NewUserMailer.new_user_email(resource).deliver_now
redirect_to users_path
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
render :new, :address => params[:address]
end
else
super
end
end
#email
Welcome, follow this link to update your password <%= link_to "My account", edit_user_password_url %></p>

Ruby/Rails: suppress superclass functions - integration of Stripe and Devise

I have a create method in my RegistrationsController, which inherits from Devise::Registrations controller. It is supposed to call Stripe and if the creation of a customer is successful, it saves the user and sends a confirmation email, which is handled by '#create' in Devise. If the call to Stripe fails, it is supposed to set a flash and not save the user or send an email, i.e. suppress the Devise 'create' method. The method works fine if the call to Stripe is successful, but if it is not successful, the user is still saved and the confirmation email is still sent.
class RegistrationsController < Devise::RegistrationsController
def create
super
#user = resource
result = UserSignup.new(#user).sign_up(params[:stripeToken], params[:plan])
if result.successful?
return
else
flash[:error] = result.error_message
# TODO: OVERIDE SUPER METHOD SO THE CONFIRM EMAIL IS
# NOT SENT AND USER IS NOT SAVED / EXIT THE METHOD
end
end
I have tried skip_confirmation!, this just bypasses the need for confirmation. resource.skip_confirmation_notification! also does not work. I have also tried redefining resource.send_confirmation_instructions; nil; end; My thought was to exit the create method altogether in the else block. How can I exit the create method or suppress 'super' in the else block, or would another approach be better? Thanks.
By calling super at the top of your override, the whole registration process will take place, signing up your user, and only then executing your code.
You need to override Devise's registrations_controller.rb create action code by copy and pasting the whole and inserting your call like this:
class RegistrationsController < Devise::RegistrationsController
# POST /resource
def create
build_resource(sign_up_params)
# Here you call Stripe
result = UserSignup.new(#user).sign_up(params[:stripeToken], params[:plan])
if result.successful?
resource.save
else
flash[:error] = result.error_message
end
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
end
end
Notice that resource.save is only called if result.successful?.

variable inside devise.en.yml file

I want to add user's email address in devise confirmation message, right now after a confirmation mail is send, devise shows me "A message with a confirmation link has been sent to your email address. Please open the link to activate your account." but what i want is to insert signed up user's email so it should be something like "A message with a confirmation link has been sent to your #{params[:user][:email]}. Please open the link to activate your account."
But instead of showing email it simply shows text. Any suggestions how to do it?
Solved this issue today so thought should post an answer for others too. Had to override devise registrations controller create action with this code:
class RegistrationsController < Devise::RegistrationsController
# POST /resource
def create
build_resource(sign_up_params)
if resource.save
# this block will be used when user is saved in database
if resource.active_for_authentication?
# this block will be used when user is active or not required to be confirmed
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
# this block will be used when user is required to be confirmed
user_flash_msg if is_navigational_format? #created a custom method to set flash message
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
# this block is used when validation fails
clean_up_passwords resource
respond_with resource
end
end
private
# set custom flash message for unconfirmed user
def user_flash_msg
if resource.inactive_message == :unconfirmed
#check for inactive_message and pass email variable to devise locals message
set_flash_message :notice, :"signed_up_but_unconfirmed", email: resource.email
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}"
end
end
end
Then make neccessary changes in devise.en.yml file and we are all set
en:
devise:
registrations:
signed_up_but_unconfirmed: "A confirmation link has been sent to %{email}. Click the link to activate your account."
P.S Check comments for what's happening
The Rails Guide for i18n covers this case : http://guides.rubyonrails.org/i18n.html#passing-variables-to-translations
In the view :
# app/views/home/index.html.erb
<%=t 'greet_username', user: "Bill", message: "Goodbye" %>
In the locale file:
# config/locales/en.yml
en:
greet_username: "%{message}, %{user}!"
UPDATE :
# app/views/home/index.html.erb
<%=t 'email_message', email: params[:user][:email] %>
# config/locales/en.yml
en:
email_message: "Your email address is : %{email}"

How do I signup without login?

I have an admin user in my application and only admin can create and activate users in this application.
When I create a user, devise made a automatic login for this new user. How I can create a user without automatic login?
You have to override Registration Controller (see tutorials like this one )
Then, looking at the original code (can be found here ), you'll have to edit the create part.
Original one :
# POST /resource
def create
build_resource
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
else
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords(resource)
respond_with_navigational(resource) { render_with_scope :new }
end
end
What you're looking for is deleting this line sign_in(resource_name, resource)
I hope I understood your problem correctly.
I'm not quite sure what you want to achieve:
Simply create a user instance, that can then log in
Create a new user and notify them their account has been created (i.e. "invite them")
In the first case, simply create a User instance with the appropriate information (check which fields you need to complete in the console: they depend on you configuration and the "strategies" you use: confirmable, lockable, etc.)
In the second case, you probably want to check out something like this: https://github.com/scambra/devise_invitable
Presuming User is your model, add a boolean field called is_active to the users table. Then use method active? in the User model:
class User < ActiveRecord::Base
#this method will be used by devise to determine if the user is "active"
def active?
#Allow user to log in if the user is confirmed AND if we are allowing
#the user to login
super and (not self.confirmed_at.nil?) and self.is_active?
end
end
To disable a user from logging in, set the field is_active to false in a before_create filter in User model. Or, set the default value as false in the migration.
Set is_active to true to allow a user to login.

Resources