Authenticated and unauthenticated routes for Devise - ruby-on-rails

I have created an application in using Rails 5. My user auth, is managed by the Devise gem.
I need to have different root paths for authenticated and unauthenticated users. I followed the tips given here. Everything seems really straight forward, but after signing in, I am still redirected to the normal root_path when clicking on my 'Home' link for example.
Here is my route.rb code:
authenticated :user do
root to: 'api/v1/private/reporting/dashboards/summaries#index', as: :authenticated_root
end
root to: 'landing#index', as: :root
Here is the code for the 'Home' link in my navbar:
- if api_v1_public_members_user_signed_in?
= link_to 'Home', authenticated_root_path
- else
= link_to 'Home', root_path
Can anybody spot something that I might be missing?
** FYI the 'api_v1_public_members_user_signed_in?' method might look unfamiliar but it's required since I'm namespacing my devise controllers. See here for more information on this.

Try wrapping both your authenticated and unauthenticated root paths under devise_scope and giving them both separate names:
devise_scope :user do
authenticated :user do
root to: 'api/v1/private/reporting/dashboards/summaries#index', as: :authenticated_root
end
unauthenticated :user do
root to: 'landing#index', as: :unauthenticated_root
end
end
Then, change your view to:
- if api_v1_public_members_user_signed_in?
= link_to 'Home', authenticated_root_path
- else
= link_to 'Home', unauthenticated_root_path

The devise docs provide a pattern for this.
Context
Rails 7
Devise 4.8.1
In routes.rb:
unauthenticated do
root "user#index"
end
authenticated :wealth_manager do
root "user#secret", as: :authenticated_root
end

Related

How to use multiple root route in rails 6?

Just updated to rails 6 and having trouble with a conditional root route
devise_scope :user do
authenticated do
root to: 'users#show'
end
unauthenticated do
root to: 'visitors#index'
end
end
I've attempted to check for the logged-in user in visitors#index and do a redirect to users#show but now I have this ugly URL '/users/:id' instead of being able to visit users#show with a clean root URL.
In my case I was able to solve this by adding an :as argument:
devise_scope :user do
authenticated do
root to: 'users#show'
end
unauthenticated do
root to: 'visitors#index', as: :visitors_url
end
end
I think the reasoning behind the change is to make it so that Rails knows where to route root_url.
Note: I found the answer on reddit where it was suggested using namespace would be cleaner.
namespace :visitors, path: nil do
root to: 'visitors#index'
end
I don't know if there is a way to make that work with devise though.

How do you link an authenticated page with Devise in Ruby?

I just set up Devise and things are working properly. However, for some reason, my page is not working together in authentication.
Here is my routes.rb file.
devise_for :users #, path_names: { sign_out: 'sign_out' }
devise_scope :user do
authenticated :user do
root 'home#index'#, as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
get "/dashboard" => "home#index"
When I type in localhost:3000, it redirects me to the devise sign in page that exists on localhost:3000/users/sign_in.
When I type in localhost:3000/dashboard, it takes me to the sign in page as intended but when I enter my credentials, it keeps on bringing me back to the same sign in page over and over again.
Here is my application_controller.rb file.
protect_from_forgery with: :exception
before_filter :authenticate_user!
My intention is to have localhost:3000 redirect me to an authenticated version of localhost:3000/dashboard where I can see everything on that page. Not sure what's happening.
I suggest you to rewrite your code:
Remove before_filter :authenticate_user! as problem with unauthorized users already handled by routes.
Remove devise_scope :user do ... end block - there is a simpler solution (below).
Your routes.rb :
authenticated :user do
root to: redirect('/dashboard'), as: :authenticated_root
end
root to: redirect('/users/sign_in')
get "dashboard" => "home#index"

Devise not redirecting where I would expect

Just migrated from Authlogic to Devise, and having a redirect issue.
I have the following:
root :to => "welcome#index"
authenticated :user do
root :to => "dashboard#show"
end
However, after loggin in, I end up on welcome#index, and not on dashboard#show as I would expect.
The devise documentation says:
After signing in a user, confirming the account or updating the
password, Devise will look for a scoped root path to redirect.
Example: For a :user resource, it will use user_root_path if it
exists, otherwise default root_path will be used.
Which only reinforces my expectation.
def after_sign_in_path_for(resource_or_scope)
new_order_path
end
Define this in your applications controller. This will route your user to a particular path after sign_in.
Additional tidbit:
If you want to route the user to a particular page after confirming through email use this in your applications controller.
def after_confirmation_path_for(resource_or_scope)
end
Try this:
resources :dashboard
authenticated :user do
root :to => "dashboard#show"
end
make sure the
root :to => "path"
after the above code and not below that.

How to set the signup page as homepage

I've just installed Devise in my RoR app.
I want my root site ( http://site.com ) displays the devise sign up page.
If the user is already logged, then redirect to the user dashboard. But, if an user go to http://site.com/dashboard and is not logged, then redirect to the home page, where the user can see the sign up.
How can I do this?
Thank you
UPDATE:
In my routes.rb there is
root :to => 'users#index'
and this in my users_controller:
def index
if user_signed_in?
render 'dashboard'
else
redirect_to new_user_registration_path
end
end
It's correct?
Add the following to your routes.rb
authenticate :user do
root :to => "user_dashboard#show"
end
root :to => "devise/sessions#new"
Change the "user_dashboard#show" to your controller#method for your dashboard.
authenticate is a devise specific method for your routes file.
Source:
http://rdoc.info/github/plataformatec/devise/master/ActionDispatch/Routing/Mapper#authenticate-instance_method

Setting Devise Login to be root page

I am using the following code for my routes:
devise_for :user,
:as => '',
:path_names => {
:sign_in => "",
:sign_out => "logout",
:sign_up => "register"
}
But when I'm logged out and I goto /logout I get the following error:
No route matches {:action=>"new",
:controller=>"devise/sessions"}
How do I setup the root path to be to :sign_in action?
To follow on from the people who are asking about the error Could not find devise mapping for path "/" there is a workaround.
You'll find that there is a clue in your logs which will probably say:
[Devise] Could not find devise mapping for path "/".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
match "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
#request.env["devise.mapping"] = Devise.mappings[:user]
So I retried the approach but instead wrapping it (as #miccet suggets) inside a scope block:
devise_scope :user do
root to: "devise/sessions#new"
end
This worked fine for me
devise_for :users
devise_scope :user do
authenticated :user do
root 'home#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
Just like this, tested on Rails Rails 4.1.0.rc1.
root :to => "devise/sessions#new"
I needed to set the default home root. I felt like I had tried this all night last night (prior to posting the question), but it's working now. If you're logged out, Devise attempts to redirect you to the root path which I had undefined.
(This was posted as a suggested edit, but should have been an answer of its own. I don't know if it makes sense or not. Dear anonymous editor: feel free to repost this answer as your own, and leave me a comment so I'll delete this copy.)
root :to => redirect("/users/login")
I got this to work with #VvDPzZ answer. But I had to modify it slightly
devise_scope :business_owner do
authenticated do
root to: 'pages#dashboard'
end
unauthenticated do
root to: 'devise/sessions#new', as: 'unauthenticated_root'
end
end
I had to ad to: in the root path declaration. I also removed the as: :authenticated_root because I already had some places in my application referencing root_path in links. By leaving out the as: :authenticated_root part I didn't have to change any of my existing links.
I guess you have different user roles. If you do you have to add a scope like this to the users resource:
devise_scope :user do
get "/logout" => "devise/sessions#destroy"
end
You can read more about overriding devise routes here:
https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
Some of these solutions are way too complex. Just use Rails:
Add 'get' 'users/root', to: 'users#root' to config/routes.rb.
In UsersController do something like:
def root
if user_signed_in?
redirect_to root_for_signed_in_user_path (or whatever)
else
redirect_to new_user_session_path
end
end
Using rails 3.2 and devise 3.2.3 I manage to setup my home page "home#index" (controller#action) as the login page making the following changes.
#1 Added the login form to the home page:
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
#2 Added methods resource_name, resource and devise_mapping to app/heldpers/application_helper.rb:
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
#3 Created a custom sessions controller app/controllers/users/sessions_controller.rb:
class Users::SessionsController < Devise::SessionsController
protected
# This method tell sessions#create method to redirect to home#index when login fails.
def auth_options
{ scope: resource_name, recall: 'home#index' }
end
end
#4 Skip the session routes and setup the custom sessions controller in config/routes.rb:
devise_for :users, path: 'auth', skip: [:sessions],
controllers: {
sessions: 'users/sessions'
}
as :user do
get 'auth/sign_in' => 'home#index', as: :new_user_session
post 'auth/sign_in' => 'users/sessions#create', as: :user_session
delete 'auth/sign_out' => 'users/sessions#destroy', as: :destroy_user_session
end
I'm new on rails and I didn't know your 'device_scope' name have to be different to your 'device_for' name. Notice my example.
I tried this a hundred times a this is why it didn't work jajaja
devise_for :user_devises, path: 'user_devises'
devise_scope :user_devise do
authenticated :user_devise do
root 'home#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end

Resources