I've installed devise on my engine and applied the following in my application.html.erb file:
<div id="user_nav">
<% if user_signed_in? %>
Signed in as <%= current_user.email %>. This cannot be cheese?
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
<% else %>
<%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
<% end %>
</div>
It shows No route matches "/users/sign_out" and it shows error for
<%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
Error Message NameError in Devise::Sessions#new
undefined local variable or method `destroy_user_session_path' for #<#<Class:0x007fb4da2e9618>:0x007fb4da2db9a0>
Rake Routes Result
Routes for Fd::Engine:
users_auth_google_oauth2_callback GET /users/auth/google_oauth2/callback(.:format) fd/omniauth_callbacks#google_oauth2
fd_test_index GET /fd/test/index(.:format) fd/fd/test#index
fd_omniauth_callbacks_google_oauth2 GET /fd/omniauth_callbacks/google_oauth2(.:format) fd/fd/omniauth_callbacks#google_oauth2
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#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) omniauth_callbacks#passthru {:provider=>/google_oauth2/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:google_oauth2)
fd_auth_index GET /fd/auth/index(.:format) fd/fd/auth#index
root GET / fd/auth#index
omniauth_callbacks_verify_otp GET /omniauth_callbacks/verify_otp(.:format) fd/omniauth_callbacks#verify_otp
omniauth_callbacks_delete_session GET /omniauth_callbacks/delete_session(.:format) fd/omniauth_callbacks#sign_out
Engine routes:
Fd::Engine.routes.draw do
devise_for :users,:controllers => { :omniauth_callbacks => "omniauth_callbacks" }, :class_name => "Fd::User", module: :devise
end
You Integrated OmniAuth in Devise, so if user gives correct credentials devise will create session , From your question i understand session is successfully created so if you want clear session just create a action in a controller(where you start session) and give
redirect_to "/users/sign_out"
or
try
redirect_to destroy_user_session_path
I hope this will work
Try this :
<%= link_to "Sign out", destroy_user_session_path, :method => :get %>
And make sure that you have below line in your config/initializers/devise.rb
config.sign_out_via = :get
Related
Happy Thursday everyone, I had a quick question on routes and redirecting. I am working on a rails assignment that asks that I redirect the router to his/her profile after signing in. How would I go about doing that? An after_sign_in method? Here is my routes:
Rails.application.routes.draw do
get 'users/show'
get 'users_controller/show'
devise_for :users
resources :users
get 'welcome/index'
root :to => 'welcome#index'
end
Users Controller:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
devise/sessions (Login Page)
<h2>Sign in</h2>
<div class="row">
<div class="col-md-8">
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autofocus: true, class: 'form-control', placeholder: "Enter email" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control', placeholder: "Enter password" %>
</div>
<div class="form-group">
<% if devise_mapping.rememberable? %>
<%= f.label :remember_me, class: 'checkbox' do %>
<%= f.check_box :remember_me %> Remember me
<% end %>
<% end %>
<%= f.submit "Sign in", class: 'btn btn-success' %>
</div>
<div class="form-group">
<%= render "devise/shared/links" %>
</div>
<% end %>
</div>
</div>
Thanks for your help! Also could anyone answer why my rake routes has two users#show? I know only one functions (the one with the user_id) so I don't know how two were created.
Rake Routes Output:
rake routes
Prefix Verb URI Pattern Controller#Action
users_show GET /users/show(.:format) users#show
users_controller_show GET /users_controller/show(.:format) users_controller#show
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#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
welcome_index GET /welcome/index(.:format) welcome#index
root GET /
welcome#index
Define after_sign_in_path_for in ApplicationController. Read this: https://github.com/plataformatec/devise/wiki/How-To%3A-Redirect-to-a-specific-page-on-successful-sign-in-and-sign-out
By default, Devise will redirect the user to the root_path after signing in. You can simply change the root setting in config/routes.rb to the desired path, or add a user_root_path, e.g.
get '/welcome' => "welcome#index", as: :user_root
as describe in the Devise wiki.
As to the two routes, note that your routes.rb includes these two statements:
get 'users/show'
resources :users
resources automatically adds a route at GET /users/:id mapping to UsersController#show, which is what you want. The other route should be removed, along with get 'users_controller/show'. More info on this can be found in the Rails Routing Guide.
In the applicaion controller
def after_sign_in_path_for(user)
the link that you want
end
in your example
def after_sign_in_path_for(user)
user_path(current_user.id)
end
My goal is to link the <%= #thing.user.username %> to the user's profile. I know it's something like:
<%= link_to #thing.user.username, %>
But what goes after the comma?
I can currently navigate to a user by going to "localhost:3000/users/UserNameHere". How do I link to that page dynamically?
Each of my Things has a line showing what user posted it. Here is how Things are displayed:
<div class='row'>
<div class='col-md-offset-2 col-md-8'>
<div class='panel panel-default'>
<div class='panel-heading text-center'>
<%= image_tag #thing.image.url(:medium) %>
</div>
<div class='panel-body'>
<p>
<strong><%= #thing.title %></strong>
</p>
<p>
<%= #thing.description %>
</p>
<p>
<%= #thing.user.username %>
</p>
<% if #thing.user == current_user %>
<%= link_to edit_thing_path(#thing) do %>
<span class='glyphicon glyphicon-edit'></span>
<% end %>
<% end %>
</div>
</div>
</div>
Here is my UsersController:
class UsersController < ApplicationController
def show
#user = User.find_by_id(params[:id])
end
end
Here are my routes:
Stynyl::Application.routes.draw do
resources :things
devise_for :users
get '/about', to: 'pages#about'
root 'things#index'
get 'users/:username' => "users#show"
end
Here is my rake routes output:
Prefix Verb URI Pattern Controller#Action
things GET /things(.:format) things#index
POST /things(.:format) things#create
new_thing GET /things/new(.:format) things#new
edit_thing GET /things/:id/edit(.:format) things#edit
thing GET /things/:id(.:format) things#show
PATCH /things/:id(.:format) things#update
PUT /things/:id(.:format) things#update
DELETE /things/:id(.:format) things#destroy
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#destroy
about GET /about(.:format) pages#about
root GET / things#index
GET /users/:username(.:format) users#show
You should stick to REST conventions in Rails, so use resources.
Replace:
get 'users/:username' => "users#show"
with:
resources :users, only: [:show]
then:
<%= link_to #thing.user.username, user_path(#thing.user.username) %>
or:
<%= link_to #thing.user.username, #thing.user %>
#and in model
def to_param
username
end
And replace params[:username] with params[:id] in your action.
Whenever I try to log in and sign up, I am hit with this error:
undefined method `username' for nil:NilClass
on these two lines:
<strong><%= #user.username %></strong> <br>
<strong><%= #user.name %></strong>
Here is the full error from the server's output:
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'sign_in' LIMIT 1
Rendered users/show.html.erb within layouts/application (2.1ms)
Completed 500 Internal Server Error in 7ms
ActionView::Template::Error (undefined method `username' for nil:NilClass):
1: <strong><%= #user.username %></strong> <br>
2: <strong><%= #user.name %></strong>
3: <%= debug #user %>
4:
app/views/users/show.html.erb:1:in `_app_views_users_show_html_erb__1133891108745893964_2164088020'
Here are my routes:
Stynyl::Application.routes.draw do
resources :things
resources :users, only: [:show]
devise_for :users
get '/about', to: 'pages#about'
root 'things#index'
end
Here is my user show view
<strong><%= #user.username %></strong> <br>
<strong><%= #user.name %></strong>
<div id="things" class="transitions-enabled">
<% #user.things.each do |thing| %>
<div class='panel panel default'>
<div class="box">
<%= link_to image_tag(thing.image.url(:medium)), thing %>
<div class='panel-body'>
<strong><p><%= thing.title %></p></strong>
<p><%= thing.description %></p>
By <%= link_to thing.user.username, thing.user %>
<% if thing.user == current_user %>
<%= link_to edit_thing_path(thing) do %>
<span class='glyphicon glyphicon-edit'></span> Edit
<% end %>
<%= link_to thing_path(thing), method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class='glyphicon glyphicon-trash'></span> Delete
<% end %>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
Here is my UsersController file:
class UsersController < ApplicationController
def show
#user = User.find_by_username(params[:id])
end
end
Output of rake routes:
Prefix Verb URI Pattern Controller#Action
things GET /things(.:format) things#index
POST /things(.:format) things#create
new_thing GET /things/new(.:format) things#new
edit_thing GET /things/:id/edit(.:format) things#edit
thing GET /things/:id(.:format) things#show
PATCH /things/:id(.:format) things#update
PUT /things/:id(.:format) things#update
DELETE /things/:id(.:format) things#destroy
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
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#destroy
about GET /about(.:format) pages#about
root GET / things#index
Edits
I also noticed that when I delete all of the code from the User show view, I can get to the signup and login pages, but they are blank. Can we safely guarantee that the problem is in the view? I'm so perplexed at how something in the show view can affect the ability to sign in and sign up!
I have also observed that when I add content to the users show view, it appears on the sign up and login pages. What on earth is going on?
The reason is because of a conflict in your routes. When matching a request to a route, Rails will go through your routes sequentially. But your order shows:
user GET /users/:id(.:format) users#show
new_user_session GET /users/sign_in(.:format) devise/sessions#new
And so Rails is passing sign_in as the :id parameter to your user show method, instead of being caught by devise's new_user_session_path. Changing the order will fix the problem.
TL:DR; devise_for :users should be declared before resources :users.
for my web app I'm using devise for the user authentication. Alas the app
doesn't return the sign in(or sign up) page, when I click on the links, but
the root page. Maybe somebody can help? Thanks!
routes.rb:
root to: 'static#home'
devise_for :users
devise_for :user, :path => '', :path_names => { :sign_in => "login", :sign_out => "logout", :sign_up => "register" }
_header.html.erb:
<header class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<%= link_to "Kung Pao", '#', id: "logo" %>
<nav>
<ul class="nav pull-right">
<li><%= link_to "Start", root_path %></li>
<li><%= link_to "Login", new_user_session_path %></li>
<li><%= link_to "Registrierung", new_user_registration_path %></li>
</ul>
</nav>
</div>
</div>
</header>
rake routes:
root / static#home
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
`enter code here` new_user_registration GET /register(.:format) devise/registrations#new
edit_user_registration GET /edit(.:format) devise/registrations#edit
PUT / devise/registrations#update
DELETE / devise/registrations#destroy
Change your config/routes.rb to be:
root to: 'static#home'
devise_for :users, :path => '', :path_names => { :sign_in => "login", :sign_out => "logout", :sign_up => "register" }
resources :users
You're setting path names for "user" but devise is looking for the pluralized resource name, which you define with no path.
I'm getting started with rails and devise for authentication and I want to make a link to sign out when a user is logged into the admin page.
What is the correct way to write the link_to code
Here's my rake routes:
admin_index /admin/index(.:format) {:controller=>"admin/home", :action=>"index"}
new_user_session GET /users/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /users/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /users/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /users/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /users/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /users/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"}
user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
home_index GET /home/index(.:format) {:controller=>"home", :action=>"index"}
root / {:controller=>"home", :action=>"index"}
I tried <%= link_to "Sign Out", destroy_user_session_path %> but when i click the link it gives me the error:
No route matches [GET] "/users/sign_out"
From this devise sample application, recommended on the Devise wiki:
<% if user_signed_in? %>
<li><%= link_to 'Edit account', edit_user_registration_path %></li>
<li><%= link_to 'Sign out', destroy_user_session_path, :method=>'delete' %></li>
<% end %>
the root error of your problem is that you haven't use RESTful routes in your "link_to".
you should correct your code to:
<%= link_to "Sign Out", destroy_user_session_path, :method => :delete %>
so that it will match the routes
DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations" }