I am following along this tutorial's authentication process - currently on the section 'User Authentication':
http://larsgebhardt.de/user-authentication-with-ruby-on-rails-rspec-and-capybara/
I received the follower test failure:
1) User Management User log in
Failure/Error: login(#writer)
ActionController::RoutingError:
uninitialized constant SessionController
# ./spec/support/user_helper.rb:6:in `login'
# ./spec/features/users_spec.rb:27:in `block (2 levels) in <top (required)>'
Here is the specific test and helper file mention in the failure message, along with other files..
spec/features/users_spec.rb
require 'spec_helper'
background do
#writer = create(:user, :writer)
end
....
scenario 'User log in' do
activate(#writer)
login(#writer)
expect(page).to have_content "Successfully logged in."
end
spec/support/user_helper.rb
module UserHelper
def login(a)
visit root_path
click_link 'Log In'
fill_in 'session[email]', with: a.email
fill_in 'session[password]', with: a.password
click_button 'Log In'
end
def logout(a)
visit root_path
click_link 'Log Out'
end
def activate(a)
visit activate_path(:code => a.activation_code)
end
end
routes.rb
resources :session
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email]).try(:authenticate, params[:session][:password])
if user
if user.is_active?
session[:user_id] = user.id
redirect_to (session[:target_url] || root_path)
flash[:notice] = "Successfully logged in."
else
redirect_to new_session_path
flash[:error] = "Account inactive. Please activate your account."
end
else
redirect_to new_session_path
flash[:error] = "Invalid email or password."
end
end
def destroy
session[:user_id] = nil
redirect_to root_path
flash[:notice] = "Successfully logged out."
end
end
new.html.erb
<h1>Log In</h1>
<%= form_for :session, url: sessions_path do |f| %>
<div>
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div>
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div>
<%= f.submit 'Log In' %>
</div>
<% end %>
rake routes
Prefix Verb URI Pattern Controller#Action
profiles_show GET /profiles/show(.:format) profiles#show
sessions_new GET /sessions/new(.:format) sessions#new
users_new GET /users/new(.:format) users#new
root GET / sessions#new
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PATCH /posts/:post_id/comments/:id(.:format) comments#update
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
sessions GET /sessions(.:format) sessions#index
POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
edit_session GET /sessions/:id/edit(.:format) sessions#edit
session GET /sessions/:id(.:format) sessions#show
PATCH /sessions/:id(.:format) sessions#update
PUT /sessions/:id(.:format) sessions#update
DELETE /sessions/:id(.:format) sessions#destroy
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
profile_index GET /profile(.:format) profile#index
POST /profile(.:format) profile#create
new_profile GET /profile/new(.:format) profile#new
edit_profile GET /profile/:id/edit(.:format) profile#edit
profile GET /profile/:id(.:format) profile#show
PATCH /profile/:id(.:format) profile#update
PUT /profile/:id(.:format) profile#update
DELETE /profile/:id(.:format) profile#destroy
activate GET /activate/:code(.:format) users#activate
_header.html.erb
About
Services
<%= link_to "Sign Up", new_user_path %>
<%= link_to "Log In", new_session_path %>
<%= link_to "Log Out", "/session", method: :delete %>
I previously had an issue with configuring the User Helper file which was solved but incase it becomes relevant, you can see the answer and state of the config file here:
Rspec email_spec issue
You need resources :sessions, you are missing the 's'.
Edit :
You are using the delete route incorrectly, you should say
<%= link_to "Log Out",session_path(pass the current signed in user here) , method: :delete %>
Related
In my application.html.erb I have a menu, which is displayed on every page. But I can't use 'sign out' link, an error appears.
undefined local variable or method 'main_page'
I have 'main_page' in my routes and I don't understand why it's not working.
I've tried to use 'sign out' link from my show view in the User controller's action, and it worked fine.
show.html
<% content_for :user_form do %>
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #user.name %>
</p>
<p>
<strong>Email:</strong>
<%= #user.email %>
</p>
<%= link_to 'Edit', edit_user_path(#user) %>
<%= link_to 'My dates', :controller => :calendar, :action => :month_for_user %>
<%= link_to 'sign out', :controller => :sessions, :action => :destroy %>
<%end%>
Why there is an error when the link is used from application.html? Although 'My dates' link works. How can I fix it?
application.html
<div id = 'user_menu' >
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= current_user.name %>
</p>
<p>
<strong>Email:</strong>
<%= current_user.email %>
</p>
<%= link_to 'Edit', edit_user_path(current_user) %>
<%= link_to 'My dates', :controller => 'calendar', :action => 'month_for_user' %>
<%= link_to 'sign out', :controller => 'sessions', :action => 'destroy' %>
<% end %>
</div>
sessions_controller
def destroy
redirect_to main_page
sign_out
end
routes
Prefix Verb URI Pattern Controller#Action
meetings GET /meetings(.:format) meetings#index
POST /meetings(.:format) meetings#create
new_meeting GET /meetings/new(.:format) meetings#new
edit_meeting GET /meetings/:id/edit(.:format) meetings#edit
meeting GET /meetings/:id(.:format) meetings#show
PATCH /meetings/:id(.:format) meetings#update
PUT /meetings/:id(.:format) meetings#update
DELETE /meetings/:id(.:format) meetings#destroy
new_user GET /users/new(.:format) users#new
users GET /users(.:format) users#index
main_page GET /main_page(.:format) welcome#domain
new_session GET /sign_in(.:format) sessions#new
signout GET /sign_out(.:format) sessions#destroy
sessions POST /sessions(.:format) sessions#create
GET /sessions/new(.:format) sessions#new
edit_session GET /sessions/:id/edit(.:format) sessions#edit
session PATCH /sessions/:id(.:format) sessions#update
PUT /sessions/:id(.:format) sessions#update
DELETE /sessions/:id(.:format) sessions#destroy
GET /sessions/:id(.:format) welcome#domain
GET /users(.:format) users#index
POST /users(.:format) users#create
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
month_for_user GET /month_for_user(.:format) calendar#month_for_user
Rails is new for me, and maybe it's a silly question, but I honestly tried to find an answer unfortunately without results. Please, help me to fix this problem! Thank you
undefined local variable or method 'main_page'
The error comes from the destroy method in your sessions_controller. It should be
def destroy
redirect_to main_page_url #or action: "main_page"
sign_out
end
I'm using devise on my Users controller right now and can't seem to destroy my users. Edit, new still work. Destroy only redirects me to showing the user attributes.
My User Controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to users_path
else
render 'new'
end
end
def index
#users=User.all
end
def edit
#user = User.find(params[:id])
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to users_path
end
def delete
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
redirect_to user_path(#user.id)
else
render 'edit'
end
end
def show
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :email, :password)
end
end
User View:
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
<table>
<tr>
<td>name</td>
<td>email</td>
<td>password</td>
</tr>
<% #users.each do |user| %>
<tr>
<td><%= link_to user.name, user_path(user.id) %></td>
<td><%= user.email %></td>
<td><%= user.password %></td>
<td><%= link_to "edit user", edit_user_path(user.id) %> </td>
<td><%= link_to "destroy user", user, method: :delete %> </td>
</tr>
<% end %>
</table>
Does it have something to do with the
<td><%= link_to "destroy user", user, method: :delete %> </td>
line? It seems like this is the line that is giving me the most trouble. I am using devise if that is relevant, and I am also having issues trying to get it fixed.
My rake routes:
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#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
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
Because you're using devise, it wont work in your regular controller.
You would have to use the registration path not the user path:
<%= link_to "Delete User", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>
When I submit this form
<h1>Log In</h1>
<%= simple_form_for sessions_path do |f| %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :remember_me, as: :boolean %>
<%= f.submit 'Log In' %>
<% end %>
It gives me this error: No route matches [POST] "/login". It is true that I don't have a route that matches that, but from what I understand, it should be POSTing to sessions#create, for which I have a route and an action. Why is it not doing this?
routes.rb
DinnerDash::Application.routes.draw do
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
get 'signup', to: 'users#new', as: 'signup'
root 'items#index'
resources :users
resources :password_resets
resources :sessions
resources :items
get "password/Resets"
get "password/create"
get "password/edit"
get "password/update"
end
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = login(params[:email], params[:password], params[:remember_me])
if user
redirect_back_or_to root_url, notice: 'Logged in!'
else
flash.now.alert = 'Unable to login.'
render :new
end
end
def destroy
logout
redirect_to root_url, notice: 'Logged out.'
end
end
rake routes
It's sorta hard to read, but the important points are that there's a GET /login, not a POST /login, and there's a GET and POST for /sessions_path.
login_path GET /login(.:format) sessions#new
logout_path GET /logout(.:format) sessions#destroy
signup_path GET /signup(.:format) users#new
root_path GET / items#index
users_path GET /users(.:format) users#index
POST /users(.:format) users#create
new_user_path GET /users/new(.:format) users#new
edit_user_path GET /users/:id/edit(.:format) users#edit
user_path GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
password_resets_path GET /password_resets(.:format) password_resets#index
POST /password_resets(.:format) password_resets#create
new_password_reset_path GET /password_resets/new(.:format) password_resets#new
edit_password_reset_path GET /password_resets/:id/edit(.:format) password_resets#edit
password_reset_path GET /password_resets/:id(.:format) password_resets#show
PATCH /password_resets/:id(.:format) password_resets#update
PUT /password_resets/:id(.:format) password_resets#update
DELETE /password_resets/:id(.:format) password_resets#destroy
sessions_path GET /sessions(.:format) sessions#index
POST /sessions(.:format) sessions#create
new_session_path GET /sessions/new(.:format) sessions#new
edit_session_path GET /sessions/:id/edit(.:format) sessions#edit
session_path GET /sessions/:id(.:format) sessions#show
PATCH /sessions/:id(.:format) sessions#update
PUT /sessions/:id(.:format) sessions#update
DELETE /sessions/:id(.:format) sessions#destroy
items_path GET /items(.:format) items#index
POST /items(.:format) items#create
new_item_path GET /items/new(.:format) items#new
edit_item_path GET /items/:id/edit(.:format) items#edit
item_path GET /items/:id(.:format) items#show
PATCH /items/:id(.:format) items#update
PUT /items/:id(.:format) items#update
DELETE /items/:id(.:format) items#destroy
password_Resets_path GET /password/Resets(.:format) password#Resets
password_create_path GET /password/create(.:format) password#create
password_edit_path GET /password/edit(.:format) password#edit
password_update_path GET /password/update(.:format) password#update
Try this
<%= simple_form_for :session, :url => sessions_path do |f| %>
# rest of the form
<% end %>
Error in Rails Tutorial (Hartl) v3.2
I'm on chapter 8 and all tests pass correctly prior to the exercises. Except two issues (I think they're related).
The dropdown-menu is not firing with bootstrap as the session destroy path appears to be incorrect. I'm also attempting to use the form_tag in place of the form_for tag and I keep getting the following error:
undefined method `[]' for nil:NilClass
Here is the new_html.erb under app/views/sessions:
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_tag sessions_path do %>
<%= label_tag :email %>
<%= text_field_tag :email %>
<%= label_tag :password %>
<%= password_field_tag :password %>
<%= submit_tag "Sign in", :class => "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
Here's the sessions_controller.rb:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
sign_out
redirect_to root_path
end
end
Finally, here's the rake routes output:
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
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
root / static_pages#home
Any help would be great.
Edit:
cbright had it. I had to modify the sessions_controller. The following two lines work as intended.
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
The session symbol used with form_for is no longer being used, so replace params[:session][:email] and params[:session][:password] with params[:email] params[:password].
This question is admittedly long. So I appreciate any support from the rubytutorial community. I am in Chapter 9, attempting to create a session for a logged-in user.
I've done the tutorial already in < Rails 3.1. Since I am now using Rails 3.1, I headed on over to Chapter 13 and linked to the (very good) Railscasts (#270) on the subject. I was able to rewrite my user sign up pretty easily thanks to has_secure_password.
When I try to log in with a user in the database I see this in the console):
No route matches {:action=>"show", :controller=>"users"}
Seems like I need to create a route and it should work. But if that is the case, why can I go 'users/1' and the view appear? I am using the route user_path(#user), #user in my sessions and users controllers (below).
Here is what I did.
Pass a form to the Session controller new action (note: I use form_tag and not form_for)
<%= form_tag sessions_path do %>
<div class="field">
<%= label_tag :email %><br />
<%= text_field_tag :email, params[:email] %>
</div>
<div class="field">
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</div>
<div class="actions">
<%= submit_tag "Sign In" %>
</div>
<% end %>
Then, create action in sessions_controller.rb
def create
#Assign object by email attribute
user = User.find_by_email(params[:email])
# User is present and has access, must be true otherwise nil object
if user && user.authenticate(params[:password])
session[:user_id] = user.id
RIGHT HERE IS THE PROBLEM
redirect_to user_path(#user), :notice => "Logged in!"
else
#Use flash.now on render not flash[]
flash.now.alert = "Invalid email or password"
render "new"
end
end
And finally Create action for users_controller.rb, which works fine.
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render "new"
#user.password.clear
#user.password_confirmation.clear
end
end
Leaving my User model:
attr_accessible :name, :email, :password, :password_confirmation
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
has_secure_password
Oh and here is my current routes.rb file
resources :users
resources :sessions, only: [:create, :new, :destroy]
root to: "pages#home"
match "/about", to: "pages#about"
match "/contact", to: "pages#contact"
match "/help", to: "pages#help"
match "/signup", to: "users#new"
match "/signin", to: "sessions#new"
match "/signout", to: "sessions#destroy"
And finally my output when I run rake routes:
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"}
sessions POST /sessions(.:format) {:action=>"create", :controller=>"sessions"}
new_session GET /sessions/new(.:format) {:action=>"new", :controller=>"sessions"}
session DELETE /sessions/:id(.:format) {:action=>"destroy", :controller=>"sessions"}
root / {:controller=>"pages", :action=>"home"}
about /about(.:format) {:controller=>"pages", :action=>"about"}
contact /contact(.:format) {:controller=>"pages", :action=>"contact"}
help /help(.:format) {:controller=>"pages", :action=>"help"}
signup /signup(.:format) {:controller=>"users", :action=>"new"}
signin /signin(.:format) {:controller=>"sessions", :action=>"new"}
signout /signout(.:format) {:controller=>"sessions", :action=>"destroy"}
It's your redirect_to #user and/or user_path(#user) lines. They generate requests to /users/:id, which apparently isn't in your routes.rb.
#user is nil in your example - you're assigning to user. What rails is telling you in a not very helpful way is that it can't route to :controller => 'users', :action => 'show' without a user.