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.
Related
I'm having some troubles with routes in Ruby on Rails v5.2.0
Currently, I have a resource called users, so that I have a controller which takes actions (for example index) whenever I start my server in localhost on port 3000 and type in my browser
localhost:3000/users/
Is there an easy way to map the requests for this resource to the app root?Basically, I'm trying to achieve this:
localhost:3000/users/ --> localhost:3000/
localhost:3000/users/new/ --> localhost:3000/new/
This is how my routes.rb file looks like right now:
Rails.application.routes.draw do
devise_for :users
get 'landing/index'
get 'welcome/index'
resources :users
root to: 'landing#index'
end
Add the following lines to your routes.rb file
Change
root to: 'landing#index'
to
root "users#index"`
and add the line
get "/new" => "users#new"
Also if you want to learn more on routing, here is the link
http://guides.rubyonrails.org/routing.html
TLDR - Rails doesn't have a root model generator for routing
You can manually create the individuals routes
get :new, to: "users#new", as: "new_user"
...
However while using the rails generators resources you are just specifying a shorthand for
scope :model do
get :new, to: "model#new", as: "new_model"
...
end
You can checkout the rails guide to routing for more specifics on explicit creation
http://guides.rubyonrails.org/routing.html
HACKY SOLUTION
root to: "users#index", as: "users"
get :new, to: "users#new", as: "new_user"
post "/", to: "users#create"
scope ":id" do
root to: "users#show"
get :edit, to: "users#edit", as: "edit_user"
patch "/", to: "users#update"
...
end
It looks that what you want is to 'mute' users from the url. An option for this is to call path: '' on users like this:
Rails.application.routes.draw do
devise_for :users
get 'landing/index'
get 'welcome/index'
resources :users, path: '' # <-- HERE
root to: 'landing#index'
end
The value you give to path: is going to replace the resource name.
In this scenario users is being replaced with an empty string '', but it could be any other string.
This will remove users. However, you must consider that root to: 'landing#index AND users#index are both pointing to localhost:3000/
Without knowing your app, an option to solve this scenario, could be to have landing#index as root for gustes (not authenticated users) and users#index as a root for authenticated users.
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
I’m using Rails 4.2.5. If a user is logged in, I want to redirect them if they visit http://localhost:3000/ to http://localhost:3000/user_objects . So I have added this to my config/routes.rb file
constraints(AuthenticatedUser) do
root :to => "user_objects"
end
root 'pages#index'
Then I have this file in lib/authenticated_user.rb …
class AuthenticatedUser
def self.matches?(request)
user_signed_in?
end
end
Unfortunately, when I’m logged in, and I access http://localhost:3000/, I get this error
NameError
uninitialized constant AuthenticatedUser
Any idea how I can redirect the user to the suggested page if someone is logged in?
Edit: My config/routes.rb file is as follows ...
resources :user_objects, except: :update do
member do
patch :create
put :create
end
get :find_by_user_object_and_day, on: :collection
get :find_totals, on: :collection
end
get "users/edit" => "users#edit"
resources :users
root 'pages#index'
get '/auth/:provider/callback', to: 'sessions#create'
get '/logout', to: 'sessions#destroy'
delete '/logout', to: 'sessions#destroy'
In the controller action for whatever root is, you can just say:
if current_user
redirect_to user_objects_path #look up the rails helper
end
The documentation on constraints recommends putting custom constraint classes to lib/constraints.
Anyway, for the class to be recognized in routes you should have it autoloaded. Add the directory where the constraint resides to the list of autoloaded directories in application.rb:
# config/application.rb
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W[...
#{config.root}/lib/constraints]
Im using rails 4.1.1 and ruby 2.1.1 and am having an issue with devise, namely my routes..I have used this many times before
devise_for :users
get 'pages/index'
# Route to Devise Login Page
devise_scope :user do
root to: "devise/sessions#new"
end
# Directing the user after login
authenticated :user do
root :to => 'pages#index'
end
But i get the error
`add_route': Invalid route name, already in use: 'root' (ArgumentError)
when trying to start the server.. I can see that root is being used twice, but like i said i have been able to do this in the past.. Is there a way around this
Thanks
Found this helpful comment here on stackoverflow
For Rails 4.0 you have to make sure you have unique names for the path
helpers, like root to: "dashboard#show", as: :authenticated_root.
Otherwise the authenticated root and the normal root route end up
having the same name for their path helpers, which Rails 4.0 no longer
allows
so I changed my authenticated root to helper like so
# Directing the user after login
authenticated :user do
root :to => 'pages#index', as: :authenticated_root
end
I'm reading the Rails Guides on routes (Routes From The Outside In), and I saw the following:
You can also use root inside namespaces and scopes as well. For
example:
namespace :admin do
root to: "admin#index"
end
root to: "home#index"
I'm trying to replicate this to see how it works, so in my config/routes.rb file I've got the following code:
namespace :admin do
root to: 'users#index'
end
I expected to be able to visit 'localhost:3000/admin' and be directed to the users#index page, but instead I got the error message 'uninitialized constant Admin'.
Am I misunderstanding what the example code is supposed to do, or is there something wrong with what I wrote?
namespace :admin, would route you to the controller Admin::UsersConroller. If you want to route /admin to UsersConroller, you should use scope instead of namespace.
scope '/admin' do
root to: 'users#index'
end
You can read more about it here