I have two devise forms used in my Ruby on rails site...how can i set different route paths for both devise form..i tried to override the after_sign_up_path..but both the forms gets redirected to same path...
I want to set different paths for each form.
Registrations Controller
class Registrations Controller < Devise::Registrations Controller
protected
def after_sign_up_path_for(resource)
'root_path'
end
end
this method calls when signup is success, so set your after signed up path here
def after_sign_up_path_for(resource)
if resource.invitation_type == "first" (please replace with actual invitation type here)
user1_path(replace with actual path)
elsif resource.invitation_type == "second" (please replace with actual invitation type here)
user2_path(replace with actual path)
else
root_path
end
end
Hope this helps!
Inside the application controller, put the code for after_sign_up_path_for path
#put these code inside applications_controller
def after_sign_up_path_for
if #{your_specific_condition}
else
root_path
end
end
You must be aware that if you want to override your registrations controller, you'll have to include the new controller in your routes:
#config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
Related
I'm building an authentication using Devise.
Creating users works, but after the creation the user is automatically logged-in and becomes redirected to the root-page.
I have created an own RegistrationController and overwritten the after_sign_up_path method:
class RegistrationsController < Devise::RegistrationsController
def after_sign_up_path_for(resource)
"/users/sign_in"
end
end
But it doesn't work.
What have I done wrong, respectively what have I missed.
I have read various other StackOverflow question already. Until now nothing has worked.
Here's my routes.rb too:
Rails.application.routes.draw do
resources :comments
resources :posts
devise_for :users, controllers: { registrations: "registrations" }
root "posts#index"
end
It seems like after you sign up successfully devise automatically log in and you cannot get login page if you still log in, correct me if I'm wrong
This is the default sign up method that ships with the RegistrationsController
# Signs in a user on sign up. You can overwrite this method in your own
# RegistrationsController.
def sign_up(resource_name, resource)
sign_in(resource_name, resource)
end
You can override it in your code.
Thanks to Nick M's answer I could solve the problem the following way:
First make sure your "routes.rb"-file has a line like here ...
Rails.application.routes.draw do
devise_for :users, :controllers => {:registrations => "registrations"}
...
end
Then create a "registrations_controller.rb"-file and add there this:
class RegistrationsController < Devise::RegistrationsController
protected
def sign_up(resource_name, resource)
sign_out :user
end
end
Doing it that way results in being redirected to the Login-form automatically, after creating a user. Exactly the behaviour I liked to accomplish.
"#sign_out(resource_or_scope = nil) ⇒ Object
Sign out a given user or scope. This helper is useful for signing out a user after deleting accounts. Returns true if there was a logout and false if there is no user logged in on the referred scope
sign_out :user # sign_out(scope)
sign_out #user # sign_out(resource)"
Source
How can I create an after-confirmation redirect in Devise?
Before I added the confirmation module the custom after_sign_up_path worked fine for the first time login/signup but now when I click the confirmation link in the email it redirects to the path I set for the after-login path (user profile).
My goal is to create a form wizard and "getting started" page to collect additional information. The obvious caveat being that this redirect will only happen one time, upon confirmation.
I tried some other solutions that have been posted on Stack Overflow but none of them seem to work any longer.
A less intrusive way of achieving this might be just overriding the after_confirmation_path_for method of Devise::ConfirmationsController.
Create a new confirmations_controller.rb in app/controllers directory:
class ConfirmationsController < Devise::ConfirmationsController
private
def after_confirmation_path_for(resource_name, resource)
your_new_after_confirmation_path
end
end
In config/routes.rb, add this line so that Devise will use your custom ConfirmationsController. This assumes Devise operates on users table (you may edit to match yours).
devise_for :users, controllers: { confirmations: 'confirmations' }
Restart the web server, and you should have it.
Essentially, you want to change around line 25 of Devise's ConfirmationsController.
This means you need to override the show action modifying the "happy path" of that if statement in the show action to your heart's content:
class ConfirmationsController < Devise::ConfirmationsController
def new
super
end
def create
super
end
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
if resource.errors.empty?
set_flash_message(:notice, :confirmed) if is_navigational_format?
sign_in(resource_name, resource)
respond_with_navigational(resource){ redirect_to confirmation_getting_started_path }
else
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
end
end
end
And a scoped route for it (I put the view and action in the registrations controller but you can change it to whatever):
devise_for :users, controllers: { confirmations: 'confirmations' }
devise_scope :user do
get '/confirmation-getting-started' => 'registrations#getting_started', as: 'confirmation_getting_started'
end
The default show action is referring to the protected after_confirmation_path_for method, so as another option, you could just modify what that method returns.
Have you checked the Devise wiki? It explains how to do this, with the after_signup_path_for being the path to define in your case.
From the wiki:
Make a new controller "registrations_controller.rb" and customize the appropriate method:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
'/an/example/path'
end
end
Then add a route to use it:
Modify config/routes.rb to use the new controller
devise_for :users, :controllers => { :registrations => "registrations" }
The solution given by #Lee Smith is working perfectly but I wish to add a little addition: We don't need to add the new and create actions while overriding the Devise confirmations controller for this case:
class ConfirmationsController < Devise::ConfirmationsController
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
if resource.errors.empty?
set_flash_message(:notice, :confirmed) if is_navigational_format?
sign_in(resource_name, resource)
respond_with_navigational(resource){ redirect_to your_desired_redirect_path }
else
respond_with_navigational(resource.errors, status: :unprocessable_entity){ render_with_scope :new }
end
end
end
Then in the route file, just add routing for the confirmations controller.
devise_for :users, controllers: { confirmations: "confirmations" }
I just went through all of this and none of the other answers worked (2015-04-09 with devise 3.4.1).
After signup, I wanted the user to be redirected to the login page with a message about a confirmation email. To get that working, here's what I had to do:
class RegistrationsController < Devise::RegistrationsController
protected
# This is the method that is needed to control the after_sign_up_path
# when using confirmable.
def after_inactive_sign_up_path_for(resource)
new_user_session_path
end
end
I just found this comment which would have sent me exactly where I needed to be much sooner.
Here is the reference to the after_inactive_sign_up_path_for that
mentions Niels: Devise wiki – marrossa Nov 13 '12 at 3:38
The confirmation_path also must be configured while working with refinerycms integrated in a rails app
I am using rails3 and gem devise and i have two roles admin and customer and i want after user
sign out admin should redirect to different path and customer should redirect to different path
when sign out..
You can get your desired functionality by using devise method after sign_out path.
but before you define these methods in application helper.
def is_admin?(user)
admin_role = Role.find(:first, :conditions => ["name = ?", "admin"])
return user.roles.include?(admin_role)
end
def is_customer?(user)
admin_role = Role.find(:first, :conditions => ["name = ?", "customer"])
return user.roles.include?(admin_role)
end
After that include application helper in application controller and define this method
def after_sign_out_path_for(resource_or_scope)
if is_admin?(current_user)
home_path = "/admin/users/sign_in"
elsif is_customer?(current_user)
home_path = "/customer"
end
respond_to?(home_path, true) ? send(root_path) : home_path
end
Hope it will work fine !!!
You can override the after_sign_out_path_for(resource) method that devise uses. Just mention the logic or just the desired redirection path after checking the roles of your user in the method. The devise session's destroy action calls the redirection path through this method.
def after_sign_out_path_for(resource)
#logic
end
Hope this is helpful..
The Devise README covers how to set up custom routes and controllers. In short you'll want to customize your routes for each model, e.g.:
devise_for :admins, :controllers => { :sessions => "admins/sessions" }
devise_for :customers, :controllers => { :sessions => "customers/sessions" }
Then create the corresponding controllers and override Devise::SessionsController#destroy, e.g.:
class Admins::SessionsController < Devise::SessionsController
def destroy
super
redirect_to ...
end
end
Using devise with Rails 3 app, I have read wiki/docs on how to customise the after sign up route, I am using confirmable module, so I think I need to override after_inactive_sign_up_path_for
I think I've done it all right, but it is completely ignoring my custom controller and still routing to the root_path after sign up. Driving me nuts.
My registration is using User model, I have copied the views for devise using the generate task; if i move them to views/registrations devise falls back to the default views (in the gem I guess), so it seems not to be 'noticing' my controller
I have this in my routes:
devise_for :users, :controllers => { :registrations => "registrations" }
match 'sign_up_done' => 'home#sign_up_done', :as => :after_sign_up
Here is my controller: (controllers/registrations_controller.rb)
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
after_sign_up_path
end
def after_sign_up_path_for(resource)
after_sign_up_path
end
end
(Added after_sign_up_path_for just in case, using confirmable)
It just seems to completely ignore my controller, is the naming wrong?
Thanks for any input!
I think your folder structure may have problems. try this structure: ( it's the same as those in Gem folder)
app/controllers/devise/registrations_controller.rb
app/views/devise/registrations/new.html.erb
app/views/devise/registrations/edit.html.erb
and the controller file looks the same as it is declared in the gem folder:
#app/controllers/devise/registrations_controller.rb
# NOT: class RegistrationsController < Devise::RegistrationsController ,
# since you are "overwriting" it.
class Devise::RegistrationsController < DeviseController
def after_inactive_sign_up_path_for(resource)
#...
end
end
I have looked all over the place, and found a lot of info... but nothing works for me and I don't get it :(
I know that you are suppose to override the registration controller, like this:
class Users::RegistrationsController < Devise::RegistrationsController
def after_sign_up_path_for(resource)
authors_waiting_path
end
end
Then following the example showed by Tony Amoyal http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/, I am supposed to change my routes to update the access the new controller:
devise_for :users, :controllers => { :registrations => "users/registrations" } do
#get '/author/sign_up', :to => 'devise/registrations#new'
#get '/client/sign_up', :to => 'devise/registrations#new'
get '/author/sign_up', :to => 'users/registrations#new'
get '/client/sign_up', :to => 'users/registrations#new'
end
Yes, I have something a bit strange here, because I am catching some specific path to send them to the registration page, this allows me to create effectively 2 registration scenario.
I commented what I had before I had overridden the registration controller.
Even with all this and my authors_waiting_path being a valid path, it just keeps on going to the sign-in page after registration :(
This is really frustrating.
Alex
edit: I also found this on the devise wiki: https://github.com/plataformatec/devise/wiki/How-To:-Redirect-after-registration-(sign-up)
But I have no idea where to define this create method ? should I override the session controller ???
edit 2:
I put a dummy override of the controller:
class Pouets::RegistrationsController < Devise::RegistrationsController
def after_sign_up_path_for(resource)
authors_waiting_path
end
def new
super
end
def create
puts "was here"
super
end
def edit
super
end
def update
super
end
def destroy
super
end
def cancel
super
end
end
And I never the "was here" in my logs.... I really have the feeling that it's totally ignoring the override... I must be doing something wrong :(
Ok... I am able to override it so you should be either :0
Create folder app/controllers/users
put there registrations_controller.rb with: (option with session - but it will try sign_in and later redirect - it may be not intended behavior for you ). Furthermore this is from devise wiki and I am not sure if it works
class Users::RegistrationsController < Devise::RegistrationsController
def create
session["#{resource_name}_return_to"] = complete_path
super
end
end
restart application (just for ensure you don't trust anything)
All in all you must override Create If you want redirect only Users... if you want define some more complex scenario you should monkeypatch sign_in_and_redirect
so your controller will looks like
class Users::RegistrationsController < Devise::RegistrationsController
# POST /resource/sign_up
def create
build_resource
if resource.save
set_flash_message :notice, :signed_up
#sign_in_and_redirect(resource_name, resource)\
#this commented line is responsible for sign in and redirection
#change to something you want..
else
clean_up_passwords(resource)
render_with_scope :new
end
end
end
second option try to monkeypatch helper ....
module Devise
module Controllers
# Those helpers are convenience methods added to ApplicationController.
module Helpers
def sign_in_and_redirect(resource_or_scope, resource=nil, skip=false)
#intended behaviour for signups
end
end
end
end
I have tried the above solution and while it works, reading devise code, I have found that all you actually need in order to sign-out just registered user and redirect is:
to add is_approved or similar to your user table and
to add active_for_authentication? method in your User model
Code:
class User < ActiveRecord::Base
# ... some code
def active_for_authentication?
super && is_approved
end
end
Was a bit hard to find when I needed it, but that is all. I am actually writing it here in case someone else needs it.