Assigning a temporary password is dangerous because the user will most likely be too lazy to change it. Also, the email could be intercepted by someone else who beats the legitimate user to changing the password. Now the account is in someone else's controler.
Instead, don't assign any password when you create the account. Use Devise's :confirmable
module:
devise :database_authenticatable, :confirmable, etc...
When confirmable
is used, as soon as the record is saved, devise will automatically send an email to the user with a link to click on to confirm the account. When the click on that link, devise will update the DB to mark the record as confirm, and then redirect them to the root_path of your Rails project.
This behavior is defined in the method after_confirmation_path_for, so override that method in your ApplicationController and have it return the url for a page where they are forced to set their password (such as edit_user_path(current_user)
if your devise model is User
).
In addition, add a before_filter to your ApplicationController so that they are forced to reset their password before continuing.
class ApplicationController < ActionController::Base private before_filter :force_user_to_set_password def force_user_to_set_password redirect_to edit_user_path(current_user), :notice => "First, create a password" if user_signed_in? && current_user.encrypted_password.blank? end def after_confirmation_path_for(resource_name, resource) __send__("edit_#{resource_name}_path", resource) endend
And, of course, prevent them from getting stuck in redirect loops:
class UsersController < ApplicationController private skip_before_filter :force_user_to_set_password, :only => [:edit, :update]end