Rails correct way to use link_to with devise - ruby-on-rails

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

Related

Error :undefined local variable or method `delete' in logout link

I am creating a login-logout link. I have used my devise for user and getting the following error.
Showing /home/sushmitha/ground/remote_modals_demo-master/app/views/layouts/_header.html.erb where line #9 raised:
undefined local variable or method `delete' for #<#:0x00007f3920c61e38>
//_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<h1><%= link_to "Cricket", root_path, id: "logo" %></h1>
<nav>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Help", '#' %></li>
<% if user_signed_in? %>
<li><%= link_to "Sign out", destroy_user_session_path, method:delete %></li>
<% else %>
<li><%= link_to "Log in", user_session_path %></li>
<% end %>
</ul>
</nav>
</div>
</header>
user routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) users/sessions#new
user_session POST /users/sign_in(.:format) users/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy
cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel
new_user_registration GET /users/sign_up(.:format) users/registrations#new
edit_user_registration GET /users/edit(.:format) users/registrations#edit
user_registration PATCH /users(.:format) users/registrations#update
PUT /users(.:format) users/registrations#update
DELETE /users(.:format) users/registrations#destroy
POST /users(.:format) users/registrations#create
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
It should be method: :delete.

routing to users device

iam trying to remember how to code since 3 months of stoping, so in my new project trying to add a link_to that goes to the device users sign_in page..kept getting this error.
NameError in Topics#index
undefined local variable or method `new_user_session' for #<#<Class:0x74e5db0>:0x54af248>
route.rb
Rails.application.routes.draw do
resources :topics
devise_for :admins, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
devise_for :users
root 'topics#index'
here is my routes
Prefix Verb URI Pattern Controller#Action
topics GET /topics(.:format) topics#index
POST /topics(.:format) topics#create
new_topic GET /topics/new(.:format) topics#new
edit_topic GET /topics/:id/edit(.:format) topics#edit
topic GET /topics/:id(.:format) topics#show
PATCH /topics/:id(.:format) topics#update
PUT /topics/:id(.:format) topics#update
DELETE /topics/:id(.:format) topics#destroy
new_admin_session GET /admin/login(.:format) active_admin/devise/sessions#new
admin_session POST /admin/login(.:format) active_admin/devise/sessions#create
destroy_admin_session DELETE|GET /admin/logout(.:format) active_admin/devise/sessions#destroy
admin_password POST /admin/password(.:format) active_admin/devise/passwords#create
new_admin_password GET /admin/password/new(.:format) active_admin/devise/passwords#new
edit_admin_password GET /admin/password/edit(.:format) active_admin/devise/passwords#edit
PATCH /admin/password(.:format) active_admin/devise/passwords#update
PUT /admin/password(.:format) active_admin/devise/passwords#update
admin_root GET /admin(.:format) admin/dashboard#index
batch_action_admin_admins POST /admin/admins/batch_action(.:format) admin/admins#batch_action
admin_admins GET /admin/admins(.:format) admin/admins#index
POST /admin/admins(.:format) admin/admins#create
new_admin_admin GET /admin/admins/new(.:format) admin/admins#new
edit_admin_admin GET /admin/admins/:id/edit(.:format) admin/admins#edit
admin_admin GET /admin/admins/:id(.:format) admin/admins#show
PATCH /admin/admins/:id(.:format) admin/admins#update
PUT /admin/admins/:id(.:format) admin/admins#update
DELETE /admin/admins/:id(.:format) admin/admins#destroy
admin_dashboard GET /admin/dashboard(.:format) admin/dashboard#index
batch_action_admin_users POST /admin/users/batch_action(.:format) admin/users#batch_action
admin_users GET /admin/users(.:format) admin/users#index
POST /admin/users(.:format) admin/users#create
new_admin_user GET /admin/users/new(.:format) admin/users#new
edit_admin_user GET /admin/users/:id/edit(.:format) admin/users#edit
admin_user GET /admin/users/:id(.:format) admin/users#show
PATCH /admin/users/:id(.:format) admin/users#update
PUT /admin/users/:id(.:format) admin/users#update
DELETE /admin/users/:id(.:format) admin/users#destroy
admin_comments GET /admin/comments(.:format) admin/comments#index
POST /admin/comments(.:format) admin/comments#create
admin_comment GET /admin/comments/:id(.:format) admin/comments#show
DELETE /admin/comments/:id(.:format) admin/comments#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
root GET / topics#index
index.erb
<div id="pre_header" class="visible-lg" style="background-color:#E4AB7E; height:5px;"></div>
<div id="header" class="container" style="background-color:#fff; background-image:none;">
<div class="row">
<!-- Logo -->
<div class="logo">
<%= link_to (image_tag 'logo.jpg',:style=>'padding:20px 50px;'), root_path %>
</div>
<!-- End Logo -->
<!-- Top Menu -->
<div class="col-md-12 margin-top-30">
<div id="hornav" class="pull-right visible-lg">
<ul class="nav navbar-nav">
<li><%= link_to 'Laman Utama', topics_path %></li>
<li>Senarai Ilmu</li>
<li>Hubungi Kami</li>
<li>Info Lanjut</li>
<li><%= link_to 'Log Masuk',new_user_session %></li>
</ul>
</div>
</div>
<div class="clear"></div>
<!-- End Top Menu -->
</div>
</div>
<div id="pre_header" class="visible-lg" style="background-color:#E4AB7E; height:5px;"></div>
It's a typo I guess. path is missing in the link. It would be new_user_session_path
<li><%= link_to 'Log Masuk',new_user_session_path %></li>

Rails Devise Engine Sign_out link Error

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

What route to use to link to resource creator?

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.

undefined method `username' for nil:NilClass when signing up and signing in

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.

Resources