Currently, when a user logs in or signs up, they are redirected to /users/1, for example, as their show page.
I can't figure out what routes to use to redirect them to just the site root (example.com, for example, instead of example.com/users/1). The logged in site root would be the show page, the logged out site root would be the normal site home page.
I'm using devise, if it matters.
Current routes:
devise_for :users, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout',
:password => 'password', :confirmation => 'verification',
:unlock => 'unblock', :registration => 'signup',
:sign_up => 'new' }
devise_scope :user do
get 'login', to: 'devise/sessions#new'
get 'users/login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
get 'signup', to: 'devise/registrations#new'
get 'password', to: 'devise/passwords#new'
match 'users/secret', to: "devise/passwords#create", via: :post
match 'sessions/user', to: 'devise/sessions#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
end
resources :users
resources :sessions
root 'site#index'
Updated Routes:
devise_for :users, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout',
:password => 'password', :confirmation => 'verification',
:unlock => 'unblock', :registration => 'signup',
:sign_up => 'new' }
get 'login' => 'users/login'
devise_scope :user do
get 'login', to: 'devise/sessions#new'
get 'users/login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
get 'signup', to: 'devise/registrations#new'
get 'password', to: 'devise/passwords#new'
match 'users/secret', to: "devise/passwords#create", via: :post
match 'sessions/user', to: 'devise/sessions#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
end
get '', to: 'users#show', as: 'user'
get 'edit', to: 'users#edit', as: 'user/edit'
#resources :users
resources :sessions
# Authenticated Users:
authenticated :user do
root to: "users#show", as: :authenticated_root
end
# Non-Authenticated Users
root to: 'site#index'
You can use authenticated and unauthenticated resources.
Like this:
authenticated :user do
root to: "users#show", as: :authenticated_root, via: :get
end
unauthenticated do
root 'site#index'
end
Then in your users controller you'll need to make sure to check for the devise helper current_user instead of the id because you aren't passing one.
like
if params[:id]
#user = User.find params[:id]
else
#user = current_user
end
If you don't want users to be able to access this route, its easier to manage in the controller. Just modify the if statement, something like
if params[:id]
if current_user
#user = current_user
else
flash[:notice] = "This page is not available"
redirect_to root_path
end
else
#user = current_user
end
Updated routes:
devise_for :users, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout',
:password => 'password', :confirmation => 'verification',
:unlock => 'unblock', :registration => 'signup',
:sign_up => 'new' }
get 'login' => 'users/login'
devise_scope :user do
get 'login', to: 'devise/sessions#new'
get 'users/login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
get 'signup', to: 'devise/registrations#new'
get 'password', to: 'devise/passwords#new'
match 'users/secret', to: "devise/passwords#create", via: :post
match 'sessions/user', to: 'devise/sessions#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
match 'users/signup', to: 'devise/registrations#create', via: :post
end
#resources :users
resources :sessions
# Authenticated Users:
authenticated :user do
root to: "users#show", as: :authenticated_root
end
# Non-Authenticated Users
root to: 'site#index'
get '', to: 'users#show', as: 'user'
get 'edit', to: 'users#edit' as: 'user'
In your routes.rb (change the destination to: to the pages you wish)
YourApp::Application.routes.draw do
...
# Authenticated Users:
authenticated :user do
root to: 'user#show', as: :authenticated_root
end
# Non-Authenticated Users
root to: 'site#index'
end
Rails 4 Fix: https://github.com/plataformatec/devise/issues/2393#issuecomment-17298414
In UserController.rb: Make sure in your show method, that you use current_user instead of params[:id]. You do this because typically whenever you call your show action you send it an id, however in this case, you're not going to be doing so.
class UsersController < ApplicationController
def show
if params[:id].present?
#user = User.find(params[:id])
else
#user = current_user
end
end
end
Related
I have this routes.rb:
devise_for :users, :path => '', path_names:
{ sign_in: "login", sign_out: "logout", sign_up: "registration"}
I changed sign_in and sign_up routes and if you go to sign_up you will get 404 error, instead /registration will work. What I want is to change and add other routes like forgotten password in the same way.
If I type in the console rake routes, I see this for forgotten password:
new_user_password GET /password/new(.:format) devise/passwords#new
How can add the additional routes in a way that my custom defined route will work, but not the default?
Be sure to checkout the ActionDispatch::Routing::Mapper#devise_for documentation here.
You can just simply do something like this-
devise_for :users, path: 'auth', path_names: { sign_in: 'login',
sign_out: 'logout',
password: 'secret',
confirmation: 'verification',
unlock: 'unblock',
registration: 'register',
sign_up: 'cmon_let_me_in' }
Here is an example for the sessions, registrations, and passwords controller actions/routes:
devise_for :users, skip: [:sessions, :registrations, :passwords]
devise_scope :user do
# sessions
get 'login', to: 'devise/sessions#new', as: :new_user_session
post 'login', to: 'devise/sessions#create', as: :user_session
delete 'logout', to: 'devise/sessions#destroy', as: :destroy_user_session
# registrations
put '/account', to: 'devise/registrations#update'
delete '/account', to: 'devise/registrations#destroy'
post '/account', to: 'devise/registrations#create'
get '/register', to: 'devise/registrations#new', as: :new_user_registration
get '/account', to: 'devise/registrations#edit', as: :edit_user_registration
patch '/account', to: 'devise/registrations#update', as: :user_registration
get '/account/cancel', to: 'devise/registrations#cancel', as: :cancel_user_registration# passwords
# passwords
get 'new-pass', to: 'devise/passwords#new', as: :new_user_password
get 'edit-pass', to: 'devise/passwords#edit', as: :edit_user_password
patch 'edit-pass', to: 'devise/passwords#update', as: :user_password
post 'new-pass', to: 'devise/passwords#create', as: :user_password
end
As seen in the 4th code sample block in this wiki
You need to skip passwords and rebuild its routes as you want,
devise_for :users, skip: [:passwords]
devise_scope :user do
match '/forgotten-password' => 'devise/passwords#create', as: :user_password, via: [:post]
match '/forgotten-password' => 'devise/passwords#update', via: [:put, :patch]
get 'forgotten-password', to: 'devise/passwords#new', as: :new_user_password
end
Your custom routes will work. And it skip all routes in that modules.
NOTE : You need to overwrite all remaining routes of that module as you want.
I am running my rails app as sub-directory (for apache mapping reasons):
config.ru:
map '/sub-directory' do
run Rails.application
end
application.rb:
config.root_directory = "/sub-directory/"
config.action_controller.relative_url_root = '/sub-directory'
so now my app (it's root) is ran from the route http://localhost:3000/sub-directory. The problem is when I go to http://localhost:3000/ I get the page:
Not Found: /
I understand I am getting that because my app isn't running in there anymore but I would like that route to redirect to http://localhost:3000/sub-directory. Is there anyway I can accomplish this?
if this helps, routes.rb:
require 'resque/server'
Rails.application.routes.draw do
get "handle/:handle" => "handles#index"
get "/tag/:hashtag" => "tags#index"
get "handles/:handle" => "handles#index"
get "/tags/:hashtag" => "tags#index"
devise_for :users, :controllers => {
:registrations => "registrations",
:passwords => "passwords"
}
devise_scope :user do
get "/email" => "registrations#email"
post "/registrations/check_email" => "registrations#check_email"
get "/users/sign_in" => "registrations#signup"
end
authenticated :user do
devise_scope :user do
root :to => redirect("app"), as: :authenticated_root
get "/app", :to => 'reports#index'
end
end
unauthenticated do
devise_scope :user do
root to: 'registrations#new'
end
end
get '/oauth' => 'social_platforms#new'
get "/auth/:provider/callback" => "social_platforms#create"
get '/login', :to => 'sessions#new', :as => :login
# match '/auth/failure' => 'sessions#failure', :via => [:get]
# get '/reports', to: 'pages#reports', as: :reports
resources :reports, only: [:show, :index]
get '/get_report', to: 'reports#get_report'
get '/check_token', to: 'reports#check_token'
mount Resque::Server.new, at: "/resque"
get '*path' => redirect('/')
end
i want to ovverride my devise routes and the sessions controller from this gem at the same time. How do i do this ?
I thought about :
devise_for :admins, :skip => [:sessions],
controllers: { sessions: "admins/sessions" }
devise_scope :admin do
get 'login' => 'devise/sessions#new', :as => :new_admin_session
post 'login' => 'devise/sessions#create', :as => :admin_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_admin_session
end
but my paths are chaging but the controller - not. How can I implement this right ?
When you specify controllers: { sessions: "admins/sessions" }, that implies that you have a file called sessions_controller.rb in this path: app/controllers/admins/sessions_controller.rb, and that it starts with:
module Admins
class SessionsController < Devise::SessionsController
If this is the controller you want your app to use, then in the devise_scope block, you must tell it to use admins/sessions, not devise/sessions, like this:
devise_scope :admin do
get 'login' => 'admins/sessions#new', :as => :new_admin_session
post 'login' => 'admins/sessions#create', :as => :admin_session
delete 'logout' => 'admins/sessions#destroy', :as => :destroy_admin_session
end
What about something like:
devise_for :admin, exclude: [:sessions] do
get '/login', to: 'sessions#new', as: :new_admin_session
post '/login', to: 'sessions#create', as: :admin_session
delete '/logout', to: 'sessions#destroy', as: :destroy_admin_session
end
I'm getting this error when I try to logout an user. I checked many posts of this same error but no one solved my error, I hope you can help me.
The error is as follows:
ActiveRecord::RecordNotFound in UsersController#destroy
Couldn't find User with 'id'=sign_out
The following is my code:
users_controller.rb
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to unauthenticated_root_path }
format.json { head :no_content }
end
end
private
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
view/users/index.html.erb
<li>
<%= link_to "Logout", destroy_user_session_path, :method => :delete %>
</li>
routes.rb
Rails.application.routes.draw do
get 'admin/index'
resources :contacts
resources :afections
resources :injuries
resources :allergies
resources :trainers
resources :idusuarios
resources :diseases
resources :weights
resources :diets
resources :exercices
resources :profiles
resources :users
devise_for :users
get '/users/sign_out' => 'devise/sessions#destroy'
devise_scope :user do
authenticated :user do
root 'pagina#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
end
move get '/users/sign_out' => 'devise/sessions#destroy' above resources :users in your routes. Routes are given priority in terms of their order in the routes file.
When you use resources :users in your routes, you have this routes:
/users
/users/:id
/users/:id/edit
and ...
So when /users/sign_out is called, , thinks the sign_out is an ID.
so change /users/sign_out to /user/sign_out for example.
BUT
if you want customize your session paths, you can do this:
customize your session paths:
as :user do
get 'user/signin' => 'devise/sessions#new', :as => :new_user_session
post 'user/signin' => 'devise/sessions#create', :as => :user_session
delete 'user/signout' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:delete, :get]
end
and skip session in devise:
devise_for :users, :skip => [:sessions]
if you want user registration, you must skip it in devise and then can use user scaffold:
as :user do
get 'user/signin' => 'devise/sessions#new', :as => :new_user_session
post 'user/signin' => 'devise/sessions#create', :as => :user_session
delete 'user/signout' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:delete, :get]
end
scope "admin" do
resources :users
devise_for :users, :skip => [:sessions, :registrations]
end
With the code below:
class TestController < ApplicationController
wrap_parameters :test, format: [:json, :xml], include: self.test_method
def self.test_method
[ :one, :two, :three ]
end
end
I get a RoutingError:
ActionController::RoutingError (undefined method 'test_method' for TestController:Class)
I tried a number of different derivations of this, but nothing is working.
EDIT: routes.rb -- was routing to api.servername/create during error:
TestApp::Application.routes.draw do
resources :subscriptions
# API subdomain
constraints subdomain: 'api' do
get '/' => 'test#index'
post '/create', to: 'test#create'
get '/status', to: 'test#show'
end
# root route
root to: 'pages#index'
# User routes
devise_scope :user do
get 'login' => 'devise/sessions#new', :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
get 'register' => 'devise/registrations#new', :as => :new_user_registration
get 'profile' => 'devise/registrations#edit', :as => :edit_user_registration
get 'users' => 'users/registrations#index'
end
devise_for :users, :skip => [:sessions], controllers: { registrations: 'users/registrations' }
end