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:
And so Rails is passing
sign_in
as the:id
parameter to your user show method, instead of being caught by devise'snew_user_session_path
. Changing the order will fix the problem.TL:DR;
devise_for :users
should be declared beforeresources :users
.