I am using the devise gem to handle all the sign up and sign in stuff. But I also want to add user profiles to my application, so I generated a user controller with only a show action. Then I added get 'users/:id' => 'users#show' to routes.rb. In fact, typing /users/1 works, but I can't find a way to name the route. What I want is to get something like show_user_path or user_path so I can link to a given user's content and show that user's profile.
Here is my routes.rb
Pinteresting::Application.routes.draw do
resources :pins
get 'users/:id' => 'users#show'
devise_for :users
root "pins#index"
get "about" => "pages#about"
And here are the routes I get with it (I highlighted the one I expect to be something like show_user_path):
pins_path GET /pins(.:format) pins#index
POST /pins(.:format) pins#create
new_pin_path GET /pins/new(.:format) pins#new
edit_pin_path GET /pins/:id/edit(.:format) pins#edit
pin_path GET /pins/:id(.:format) pins#show
PATCH /pins/:id(.:format) pins#update
PUT /pins/:id(.:format) pins#update
DELETE /pins/:id(.:format) pins#destroy
#this is the one I want a path! GET /users/:id(.:format) users#show
new_user_session_path GET /users/sign_in(.:format) devise/sessions#new
user_session_path POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session_path DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password_path POST /users/password(.:format) devise/passwords#create
new_user_password_path GET /users/password/new(.:format) devise/passwords#new
edit_user_password_path GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration_path GET /users/cancel(.:format) devise/registrations#cancel
user_registration_path POST /users(.:format) devise/registrations#create
new_user_registration_path GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration_path GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root_path GET / pins#index
about_path GET /about(.:format) pages#about
For devise, User is not the resource, it's just a scope. What devise cares about is authentication.
Although the paths are nested under /user, you will notice that the resources that are defined are actually things like sessions, registrations, passwords...
Just add resources :users in your routes and create a UsersController (and the views).
If you don't want to create all the resources for users and just be able to user user_path(user) with your get 'users/:id, you can name that route using the as option, like this:
get 'users/:id' => 'users#show', as: user
The answer above is great but I think it's worth noting here that if you don't want to create a different controller, but want to add an action to, say, your registrations controller that you inherit from the Devise::RegistrationsController, then you need to use the devise scope block:
devise_scope :user do
get 'users/:id' => 'registrations#show', as: user
end
the answer supposed to be like this:
get 'user/:id' => 'users#show', as: :user
Related
I am using Devise Gem for authentication but for the index/root page for my application I want to use sign_in page of devise gem.
I have used the following code in the config/routes.rb file
root 'devise/sessions#new'
I am getting the following error
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 get "/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]
Here is snapshot of my rake routes output
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destro
workout_schedules_find POST /workout_schedules/find(.:format) workout_schedules#find
workout_schedules GET /workout_schedules(.:format) workout_schedules#index
POST /workout_schedules(.:format) workout_schedules#create
new_workout_schedule GET /workout_schedules/new(.:format) workout_schedules#new
edit_workout_schedule GET /workout_schedules/:id/edit(.:format) workout_schedules#edit
workout_schedule GET /workout_schedules/:id(.:format) workout_schedules#show
PATCH /workout_schedules/:id(.:format) workout_schedules#update
PUT /workout_schedules/:id(.:format) workout_schedules#update
DELETE /workout_schedules/:id(.:format) workout_schedules#destroy
Try to set your route file like this:
devise_scope :user do
authenticated :user do
root 'home#dashboard', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
Devise provides some inbuilt methods like authenticated, unauthenticated etc. So as per your requirement, you can set different root for logged in users and non-logged in users.
:as will create custom named url helpers like authenticated_root_path and unauthenticated_root_path
If you will run rake routes, you will get:
authenticated_root GET / home#dashboard
unauthenticated_root GET / devise/sessions#new
Here's my working example of how to solve this:
Rails.application.routes.draw do
# This is the fix.
devise_for :users, skip: :all
devise_scope :user do
get "/users/sign_in", to: "devise/sessions#new", as: :new_user_session
post "/users/sign_in", to: "devise/sessions#create", as: :user_session
delete "/users/sign_out", to: "devise/sessions#destroy", as: :destroy_user_session
get "/users/password/new", to: "devise/passwords#new", as: :new_user_password
get "/users/password/edit", to: "devise/passwords#edit", as: :edit_user_password
patch "/users/password", to: "devise/passwords#update", as: :user_password
put "/users/password", to: "devise/passwords#update"
post "/users/password", to: "devise/passwords#create"
get "/users/cancel", to: "devise/registrations#cancel", as: :cancel_user_registration
get "/users/sign_up", to: "devise/registrations#new", as: :new_user_registration
get "/users/edit", to: "devise/registrations#edit", as: :edit_user_registration
patch "/users", to: "devise/registrations#update", as: :user_registration
put "/users", to: "devise/registrations#update"
delete "/users", to: "devise/registrations#destroy"
post "/users", to: "devise/registrations#create"
end
end
I'm trying to add Devise to an existing Rails 3.2.16 app.
I have the basics working, but I'd like to create an admin role that is able to edit any user profile without entering a password.
I used the code from Option 2 - Adding an admin attribute in the Devise Wiki "Add An Admin Role" section to set up the admin role.
My routes.rb has this:
devise_for :users, :controllers => { :registrations => :registrations }
scope "/admin" do
resources :users
end
This gives me the following routes
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format)devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
admin_edit_user GET /admin/users/:id/edit(.:format) users/registrations#edit
users GET /admin/users(.:format) users#index
POST /admin/users(.:format) users#create
new_user GET /admin/users/new(.:format) users#new
edit_user GET /admin/users/:id/edit(.:format) users#edit
user GET /admin/users/:id(.:format) users#show
PUT /admin/users/:id(.:format) users#update
DELETE /admin/users/:id(.:format) users#destroy
The user views (devise/registrations/edit, etc) are hooked up correctly and work just fine, but the admin views are all pulled from the users folder (users/edit, etc), which means they bypass Devise.
For instance, my admin user edit form should probably have some variation on this in the form_for:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
but that code doesn't pull in any of the user data (all form fields are empty). The only way I can get it to show up is with the old code:
<%= form_for #user do |f| %>
Which then uses the update method from my users_controller, NOT from the Devise registrations_controller.
I've tried lots of variations on the routes because that seems to be key, but non of my attempts have worked. Help?
In order for your form_for helper to properly route your request through Devise, you need to declare your admin/users resource routes as Devise routes:
# config/routes.rb
devise_for :users, :controllers => { :registrations => :registrations }
scope "/admin" do
devise_for :users, :controllers => { :registrations => :registrations }
end
You'll continue to retain Devise functionality while being able to utilize the admin namespace for authorization purposes.
I have added custom routes for the devise actions. this does not work when I try to go to /profile/edit or /login or /logout Here is the rake routes:
saasbook#saasbook:~/Documents/ronde$ rake routes
static_about GET /static/about(.:format) static#about
static_tour GET /static/tour(.:format) static#tour
static_home GET /static/home(.:format) static#home
static_terms_of_use GET /static/terms_of_use(.:format) static#terms_of_use
static_contact GET /static/contact(.:format) static#contact
users_profile GET /users/profile(.:format) registrations#edit
login GET /login(.:format) devise/sessions#new
logout GET /logout(.:format) devise/sessions#destroy
register GET /register(.:format) devise/registrations#new
profile_edit GET /profile/edit(.:format) devise/registrations#edit
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session GET /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) omniauth_callbacks#passthru {:provider=>/google|facebook/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:google|facebook)
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / static#home
Here is my routes.rb file where I added the the new routes with the same controller actions for devise:
Ronde::Application.routes.draw do
get "static/about"
get "static/tour"
get "static/home"
get "static/terms_of_use"
get "static/contact"
get "/user/profile", :to => 'registrations#edit'
get "/login", :to => "devise/sessions#new" # Add a custom sign in route for user sign in
get "/logout", :to => "devise/sessions#destroy" # Add a custom sing out route for user sign out
get "/register", :to => "devise/registrations#new" # Add a Custom Route for Registrations
get "profile/edit", :to => "devise/registrations#edit"
devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
root to: 'static#home'
end
# :path_names => {:edit => "profile/edit", :sign_in => "login", :sign_out => "logout", :sign_up => "register" }
Then page says that and should route to the devise controller:
Routing Error
No route matches [GET] "/profile/edit"
Try running rake routes for more information on available routes.
I don't know if this right but I think you can't do that way, because Devise doesn't have any controller. Please check this question and this.
What I done usually was making another controller for Devise, or normal controller like users_controller with it own views. And register it on routes.rb like:
devise_for :users
scope "/admin" do
resources :users
end
Then when I need to open it, I called localhost:3000/admin/users
But please correct me if there anything wrong, or my way to do it was wrong. Hope can help.
I 'm trying to redirect to a specific page after sign_in & sign_up. I have two models users & resources. After sign_in I want to show list of documents that belong to the user.
If there are no documents then it should redirect to users/:id/document#create otherwise users/:id/document#index.
Any suggestions how do i do that?
I get the following error for the redirect path defined in my controller.
ActiveRecord::RecordNotFound in DocumentsController#show
Couldn't find Document without an ID
Application_controller.rb
def after_sign_in_path_for(user)
user_documents_url(user)
end
Routes.rb
root :to => 'home#index'
devise_for :users
resources :users do
resources :documents
end
devise_for :users do get '/users/sign_out' => 'devise/sessions#destroy' end
Routes
root / home#index
new_user_session GET /login(.:format) devise/sessions#new
user_session POST /login(.:format) devise/sessions#create
destroy_user_session DELETE /logout(.:format) devise/sessions#destroy
user_password POST /password(.:format) devise/passwords#create
new_user_password GET /password/new(.:format) devise/passwords#new
edit_user_password GET /password/edit(.:format) devise/passwords#edit
PUT /password(.:format) devise/passwords#update
cancel_user_registration GET /cancel(.:format) devise/registrations#cancel
user_registration POST / devise/registrations#create
new_user_registration GET /sign_up(.:format) devise/registrations#new
edit_user_registration GET /edit(.:format) devise/registrations#edit
PUT / devise/registrations#update
DELETE / devise/registrations#destroy
user_confirmation POST /confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /confirmation/new(.:format) devise/confirmations#new
GET /confirmation(.:format) devise/confirmations#show
user_documents POST /users/:user_id/documents(.:format) documents#create
new_user_documents GET /users/:user_id/documents/new(.:format) documents#new
edit_user_documents GET /users/:user_id/documents/edit(.:format) documents#edit
GET /users/:user_id/documents(.:format) documents#show
PUT /users/:user_id/documents(.:format) documents#update
/user/:user_id/documents(.:format) user/documents#index
Thanks
The code itself has no problem as I see. But you need to build some "documents" data before this test, either by FactoryGirl or stubs.
Because you really don't have "documents" data for any users, of course Rails gave you to RecordNotFound error.
use this method according to following code
def after_sign_in_path_for(resource_or_scope)
// redirect path
end
i hope this will help
I fixed my problem by following this question.Following is my routes.rb
resources :users do
resources :documents, only: [:index]
end
resource :documents, except: [:index]
this gives me document#index path as well as document#new path.
I'm having a problem testing my new user profile page with Rspec. It's working through the browser, but Rspec is blowing up.
I'm using devise with a separate controller for editing profile fields.
This is a request spec.
it 'Shows the user profile with their non-private data' do
visit user_path(#user)
page.should have_content #user.full_name
end
Fails with this error:
Failure/Error: visit user_path(#user)
ActionController::RoutingError:
No route matches {:action=>"show", :controller=>"users"}
I disagree
#routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
resources :users, :only => [:edit, :update, :show]
The update and edit path helpers are working just fine.
The controller action:
class UsersController < ApplicationController
layout 'profile', :except => [:show]
#... edit and update omitted
def show
#user = User.find(params[:id])
end
end
rake routes shows:
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
So it doesn't really look like devise is interfering with my route, and more importantly, everything works in the browser. What am I missing here?
I also tried making a member action called profile instead of the default show, that had the same result
The problem here was I started a new context block and didn't set up #user before the it block. The route thing was just a red herring.
Also proof that you should walk away from your code for awhile if you can't figure things out.