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
Related
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 %>
Right out of the Rails Tutorial. I can't get the sign in form to call the create method. Debug shows it only calls the new action. I had no issues setting up the users which also has a database so the following was utilized:
<%= form_for #user do |f| %>
In this case, with no model, I'm doing as the tutorial suggests:
<%= form_for(:session, url: sessions_path) do |f| %>
A quick glance at rake routes shows the route is valid:
Prefix Verb URI Pattern Controller#Action
root GET / site_pages#root
about GET /about(.:format) site_pages#about
signup GET /signup(.:format) users#new
signout DELETE /signout(.:format) sessions#destroy
signin GET /signin(.:format) sessions#new
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
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
Not sure what I'm missing. Been messing with it for over an hour. Tried changing to form_tag and it's still reacting in the same way. I've edited the routes and the form in multiple ways to trigger the correct functioning with no luck.
What am I missing? Thanks.
Controller added:
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
#SIGN IN AND REDIRECT
else
flash.now[:danger] = "Invalid Submission. Please Try Again."
render 'new'
end
end
<div class="form-horizontal" role="form">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= render 'layouts/flash' %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Log In", class: "btn btn-primary btn-width-30" %>
<% end %>
</div>
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 %>
I am encountering a routing error when I try to render a partial in an ajax call:
Routing Error
No route matches {:action=>"destroy", :controller=>"relationships", :user_id=>#<User id: 2, username: .....
Within my app, I have a list of followers for a user displayed on the profile page. Instead of paginating the followers, I would like to try to return the next offset of followers from the server through AJAX. My view already utilizes partials for displaying a list of these followers (limited to 5 records).
My goal is to use an AJAX call to return this partial with the next offset of records formated (I haven't implemented the functionality to return offset records yet - I'm just trying to get the ajax working first). The partials work fine when I visit the profile page in my browser (and view the first 5 records), the error occurs when I make the AJAX call.
Here is the form in the view where the ajax call originates:
<%= form_tag user_relationships_path(#user), method: :get, remote: true do %>
<%= submit_tag 'load more...' %>
<% end %>
Here is the route:
resources :users, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
resources :relationships, only: [:create, :destroy, :index]
end
Here is my controller action (relationships#index) which responds to the request:
def index
#user = User.find_by_username(params[:user_id])
respond_to do |format|
format.js { render 'load_followers' }
end
end
The load_followers.js.erb partial:
$('ul#followers').append("<%= render 'users/following_items', users: #user.followers %>")
The users/following_items.html.erb partial:
<% users.each do |user| %>
<li class="clearfix">
<div class="box-gravatar pull-left">
<%= link_to user do %>
<%= gravatar_for user, 40 %>
<% end %>
</div>
<div class="pull-right">
<%= render 'relationships/follow', user: user %>
</div>
<%= link_to user.username, user %>
<div class="box-author">joined <%= join_date_for user %></div>
</li>
<% end %>
And finally the relationships/follow.html.erb partial:
<% unless current_user?(user) %>
<% if current_user.following? user %>
<p><%= link_to 'unfollow', user_relationship_path(user), method: :delete, class: "btn" %></p>
<% else %>
<p><%= link_to 'follow', user_relationships_path(user), method: :post, class: "btn btn-primary" %></p>
<% end %>
<% end %>
I have tracked down the offending code to the relationships/follow.html.erb partial. When that is removed, the ajax call works fine and the partial is appended to the end of the ul. Clearly it has to do with rails having an issue with the link_to to the relationships#destroy method - however, nothing I've tried seems to work.
Edit: Here are the results of running rake routes:
root / posts#index
posts_test /posts/test(.:format) posts#test
submit /submit(.:format) posts#new
signup /signup(.:format) users#new
login /login(.:format) sessions#new
logout DELETE /logout(.:format) sessions#destroy
about /about(.:format) about#index
search /search(.:format) search#index
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
post_comments POST /posts/:post_id/comments(.:format) comments#create
post_votes POST /posts/:post_id/votes(.:format) votes#create
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
post GET /posts/:id(.:format) posts#show
user_relationships GET /users/:user_id/relationships(.:format) relationships#index
POST /users/:user_id/relationships(.:format) relationships#create
new_user_relationship GET /users/:user_id/relationships/new(.:format) relationships#new
edit_user_relationship GET /users/:user_id/relationships/:id/edit(.:format) relationships#edit
user_relationship GET /users/:user_id/relationships/:id(.:format) relationships#show
PUT /users/:user_id/relationships/:id(.:format) relationships#update
DELETE /users/:user_id/relationships/:id(.:format) relationships#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
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
categories GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
category GET /categories/:id(.:format) categories#show
/:category(.:format) posts#index
Thanks!
Notices your rake routes outputted this line:
DELETE /users/:user_id/relationships/:id(.:format)
This means your named route user_relationship is expecting both user and relationship IDs. Reason being, relationship is a nested resource of user.
So for instance you currently have this in your link to:
= link_to 'unfollow', user_relationship_path(user), method: :delete, class: "btn"
Instead it should be something like:
= link_to 'unfollow', user_relationship_path(user, relationship), method: :delete, class: "btn"
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].