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.
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"
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.
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
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