I have a Rails application that uses Devise for user authentication. If a user registers using the registration form, but he happens to use an existing valid username/password, instead of giving an error, I want to just log in the user. But I can't figure out how to do that.
Any suggestions?
You will need to override the devise RegistrationsController create action. After the regular registration code, you will need to add your code to check if a user already exists and sign in if the email/pass combination match. Something like this (based on the devise version you are using - this is based on the source of 2.2.4)
class RegistrationsController < Devise::RegistrationsController
def create
build_resource
if resource.save
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
# Add code to check if user exists and sign in
# I am just pasting in the sign_in code here and you will need to customize it as per your needs
# You can directly use params and User model, or try an keep your code generic
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
end
end
end
And add the controller to your routes as well:
devise_for :users, :controllers => { :registrations => "registrations"}
Related
By default with devise. After a user registers it automatically signs them in after sign up. Is there anyway to register a user and not auto sign them in and redirect to the login page?
You need to override Devise::RegistrationsController#create. You can see how registration works here
First, create a custom controller subclass of Devise::RegistrationsController
class RegistrationController < Devise::RegistrationsController
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
respond_with resource, location: root_path # Change this to whatever route your want
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
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
end
end
Then tell devise to use custom controller:
devise_for :users, :controllers => {:registrations => "registrations"}
Assuming User is the model of course.
I have a registration form, and after registration I want browser to remember user's (still unconfirmed) email. How could I do that? I assume I can do this somehow with build_resource of RegistrationsController.
Assuming you want to remember the last registered/un-confirmed user you could do this:
Create new folder under app/controllers called my_devise
Create a file called registrations_controller.rb in app/controllser/my_devise:
class MyDevise::RegistrationsController < Devise::RegistrationsController
# POST /resource
def create
build_resource
if resource.save
# here we save the registering user in a session variable
session[:registered_as] = resource
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
clean_up_passwords resource
respond_with resource
end
end
end
Update the config/routes.rb file to tell Devise to use our new controller:
devise_for :users,
:controllers => {
:registrations => 'my_devise/registrations'
}
After registration, the session variable :registered_as will now hold the last user that registered and could be referenced in any controller or view:
some_view.html.rb:
<p>Registered as:
<%= session[:registered_as].inspect %>
</p>
See also: Override devise registrations controller
User model has one user_profile.
I just installed devise and its working fine.
I made registrations_controller.rb and it has 'create', 'after_update_path_for(resource)
', and 'edit' actions.
If I want to make it input '45' to nested column of user_profile as default value, how can I code in registration controller???
Should I make another action called 'save/or new?' , and write this?
#user.user_profile.language_id = '45'
I was making some tests, and I suggest you to use callbacks, but you can also override the actions of the RegistrationsController of Devise. I followed this thread: Override devise registrations controller and the code of the controller https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb (see that I use sign_in instead of sign_up - I'm working with Rails 3.2.8)
And this is the code with the edits for the case:
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
build_resource
resource.build_user_profile
resource.user_profile.language_id = 45
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 => 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
clean_up_passwords resource
respond_with resource
end
end
def update
super
end
end
And as the answer of the post said, I leave the routes as follows:
devise_for :users, :controllers => {:registrations => "registrations"}
I used a has_one relationship.
Use Case:
Admin should be able to create user, and it should not attempt to login.
Public User can crate account and after signup he should be redirected to sign-in page rather signing him in immediately.
Can somebody help me with this ?
Thanks :)
What you need to do is to override Devise's RegistrationsController create method.
There is an excellent explanation for how to do it here.
This is Devise create action:
# 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 => 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
clean_up_passwords resource
respond_with resource
end
end
After you override the controller, just remove sign_in(resource_name, resource)
You can also set the method after_sign_up_path_for(resource) to fit your needs
I have a sign up mechanism which completes after link to activation through confirmable. now i want to remove confirmable and i want user to directly login after the sign up. please tell me what changes i need to do and how can i do this? do i also need to remove confirmation fields from db? please tell me the whole procedue.
you need to use #user.skip_confirmation! before saving user in db.
If you are using registration_controller then the #user object will be resource like.
This is registrations_controller create method.
def create
build_resource
resource.skip_confirmation!
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 => inactive_reason(resource) 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
Just remove the confirmable module from the User model.
devise :confirmable, …