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>
Related
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
So I have a user model via devise and a collective model. I'm trying to create an invite system such that a user can invite a person to the website via email. When this person joins the website, a user is created and this new user will automatically be added to a collective using a token (the collective they are added to is chosen by the inviting user). I have the invite system working up to the point that a non-user receives an email with a sign up link (with a token in the url) and gets to the sign up page. I cannot however manage to get this person added to a collective once they submit the registration form.
I am currently getting the error Validation failed: Owner can't be blank due to the line resource.collectives.push(org)in the create action. Help would be much appreciated!
My Custom Registrations Controller (I copied & slightly modified the Devise Registration Controller code)
class RegistrationsController < Devise::RegistrationsController
def new
#token = params[:invite_token]
build_resource({})
#validatable = devise_mapping.validatable?
if #validatable
#minimum_password_length = resource_class.password_length.min
end
yield resource if block_given?
respond_with self.resource
end
def create
build_resource(sign_up_params)
#added #token
#token = params[:invite_token]
resource_saved = resource.save
#added if #token logic
if #token != nil
org = Invite.find_by_token(#token).collective
resource.collectives.push(org)
end
yield resource if block_given?
if resource_saved
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
#validatable = devise_mapping.validatable?
if #validatable
#minimum_password_length = resource_class.password_length.min
end
respond_with resource
end
end
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!"
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}"
In my rails application I want to accept any string that comes after "users/" link. How do I do it? That is eg. users/xyz or user/asdas is acceptable. How do I do this?
def store_location
# store last url - this is needed for post-login redirect to whatever the user last visited.
if (request.fullpath != "/users/sign_in" &&
request.fullpath != "/users/sign_up" &&
request.fullpath != "/users/password" &&
!request.xhr?) # don't store ajax calls
session[:previous_url] = request.fullpath
end
end
Okay, here is the full story. I have implemented this along with letting user to sign in only if he is approved. The catch is I need to do it for only one type of user so I implemented this in registrations_controller.rb by overriding it.
def create
build_resource(sign_up_params)
if resource.save
# nil
if !resource.has_role? :customer
if resource.active_for_authentication?
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
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
resource.approved=true
resource.save
# nil
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)
end
else
clean_up_passwords resource
respond_with resource
end
end
So customer alone can be directly approved but not others. So, when the users get the confirmation email and they click the link they get logged in but get confirmation token invalid error that is probably due to the page getting rerouted back to the confirmation token even on signing in and going to the root path which I have set in the after_sign_in_path. That is why I am trying a work around.
Is this the error or is this something else?
I have solved the problem by using the following code. This make sure when the users clicks the confirmation link he is not redirected back to the confirmation link again on signing in as the confirmable module logs us in after confirmation right away.
I am using Rails 4, Devise version 3.03.
def store_location
# store last url - this is needed for post-login redirect to whatever the user last visited.
if (!request.fullpath.match("/users/") &&
!request.xhr?) # don't store ajax calls
session[:previous_url] = request.fullpath
end
end
This will return the string after "users/" or nil if it does not match:
def getUser(str)
matched = /users\/(.+)/.match(str)
if(matched != nil)
return matched[1]
else
# did not match format
end
return nil
end
Check out the demo here: http://rubyfiddle.com/riddles/94766