I'm new to RoR and have been working my way through the Hartl tutorial (which has been great). I've followed up through Chapter 9 successfully (tweaking things a bit since my ultimate goal is not to make a microposts site). At that point, I decided that I would like to add a 'remember me' check box and reset password functionality to my app, so I bounced over to the railscast tutorial (as suggested by Hartl). The check box went very smoothly, but I've hit a brick wall with the password reset section. It's been one error after the next. I have to admit that I couldn't help myself and tweak a little - I tried to use theform_for syntax instead of the form_tag syntax. I've gotten as far as being able to submit an email address, but then I get a No route matches [POST] "/reset_password/new" message. I've spent the last two days reading similar posts on stackoverflow and trying out the suggestions, but I just can't seem to come up with something that works. Please help!
Here's the nitty gritty:
My password reset view is located at /app/views/reset_password/new.html.erb:
<% provide(:title, 'Reset Password') %>
<h1>Reset Password</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for #user, url: new_reset_password_path do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.submit "Reset Password", class: "btn btn-large btn-methyl" %>
<% end %>
</div>
</div>
My controller is located at /app/controllers/reset_password_controller.rb:
class ResetPasswordController < ApplicationController
def new
#user = User.new
end
def show
end
def create
#user = User.find_by_email(params[:email].downcase)
user.send_password_reset if user
redirect_to root_path, notice: "Email sent with password reset instructions."
end
def edit
#user = User.find_by_password_reset_token!(params[:id])
end
def update
#user = User.find_by_password_reset_token!(params[:id])
if #user.reset_password_sent_at < 2.hours.ago
redirect_to_new password_reset_path, alert: "Reset password request has expired."
elsif #user.update_attributes(params[:user])
redirect_to root_path, notice: "Password has been reset!"
else
render :edit
end
end
end
My routes are located at /config/routes.rb:
Methylme::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :reset_password
root to: 'static_pages#home'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
.
.
.
end
Finally, $ rake routes reports the following:
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
reset_password_index GET /reset_password(.:format) reset_password#index
POST /reset_password(.:format) reset_password#create
new_reset_password GET /reset_password/new(.:format) reset_password#new
edit_reset_password GET /reset_password/:id/edit(.:format) reset_password#edit
reset_password GET /reset_password/:id(.:format) reset_password#show
PUT /reset_password/:id(.:format) reset_password#update
DELETE /reset_password/:id(.:format) reset_password#destroy
root / static_pages#home
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
Thanks in advance for your help!
I don't think you want to link to new_reset_password_path (new) in your password reset view, but to reset_password_path (create), which does send the reset password email.
If your routes don't do what you expect (for instance, the create route does not have an associated xxx_path name) you should simply declare them individually, with
post '/reset_password', to: 'reset_password#create', as: 'send_reset_password' # for example
...
This is one of the best authentication tutorial by Ryan,
http://railscasts.com/episodes/250-authentication-from-scratch-revised
Related
The issue is I get this nasty little controller error...
NoMethodError in Contacts#new
undefined method `contacts_path' for #<#:0x0000000124b228>
Did you mean? contact_path
on my view: contact#new
<%= form_for #contact do |f| %>
<div class="col-xs-6 form-group contact-input">
<h1><%= f.label :Feedback %></h1>
<%= f.text_area :text, class: "input-lg form-control", rows: "10" %>
<%= f.submit "Send Feedback", class: "btn btn-primary btn-lg" %>
</div>
<% end %>
controller: contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new
if #contact.save
redirect_to '/'
flash[:success] = "Thanks for the Post!"
else
redirect_to contact_path
flash[:alert] = "Please provide input!"
end
end
end
migration:
class CreateContacts < ActiveRecord::Migration
def change
create_table :contacts do |t|
t.text :text
t.timestamps null: false
end
end
end
The error is complaining about line 3 in the view. My model is contact.rb incase I have a plural issue somewhere, but I really do not think that I do. Any help would be much appreciated. This is rails 4.2... I am also a rails beginner.
I know I don't have the flash even setup yet.
rake routes:
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
about GET /about(.:format) static_pages#about
news GET /news(.:format) static_pages#news
advertise GET /advertise(.:format) static_pages#advertise
fishing GET /fishing(.:format) static_pages#fishing
signup GET /signup(.:format) users#new
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
contact GET /contact(.:format) contacts#new
contact_index GET /contact(.:format) contact#index
POST /contact(.:format) contact#create
new_contact GET /contact/new(.:format) contact#new
edit_contact GET /contact/:id/edit(.:format) contact#edit
GET /contact/:id(.:format) contact#show
PATCH /contact/:id(.:format) contact#update
PUT /contact/:id(.:format) contact#update
DELETE /contact/:id(.:format) contact#destroy
forum_comments GET /forums/:forum_id/comments(.:format) comments#index
POST /forums/:forum_id/comments(.:format) comments#create
new_forum_comment GET /forums/:forum_id/comments/new(.:format) comments#new
edit_forum_comment GET /forums/:forum_id/comments/:id/edit(.:format) comments#edit
forum_comment GET /forums/:forum_id/comments/:id(.:format) comments#show
PATCH /forums/:forum_id/comments/:id(.:format) comments#update
PUT /forums/:forum_id/comments/:id(.:format) comments#update
DELETE /forums/:forum_id/comments/:id(.:format) comments#destroy
forums GET /forums(.:format) forums#index
POST /forums(.:format) forums#create
new_forum GET /forums/new(.:format) forums#new
edit_forum GET /forums/:id/edit(.:format) forums#edit
forum GET /forums/:id(.:format) forums#show
PATCH /forums/:id(.:format) forums#update
PUT /forums/:id(.:format) forums#update
DELETE /forums/:id(.:format) forums#destroy
logout DELETE /logout(.:format) sessions#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
routes.rb :
Rails.application.routes.draw do
root 'static_pages#home'
get 'about' => 'static_pages#about'
get 'news' => 'static_pages#news'
get 'advertise' => 'static_pages#advertise'
get 'fishing' => 'static_pages#fishing'
get 'signup' => 'users#new'
resources :users
get 'contact' => 'contacts#new'
resources :contact
resources :forums do
resources :comments
end
delete 'logout' => 'sessions#destroy'
resources :sessions, only: [:new, :create]
end
Change resources :contact to resources :contacts in your routes.rb
I am an idiot and thanks to Zepplock just thinking about my routes showed my problem. The get
get 'contact' => 'contacts#new'
was the problem I had. I also switched my resources :contact to :contacts. All my issues were solved. Thanks for asking for the right stuff again Zepplock!
Pretty new to rails as I'm working through the Hartl tutorial. Coming up with an issue that can't quit seem to figure out.
I'm setting up password reset but when clicking on url on generated email I get the following error:
ActionController::RoutingError (No route matches [GET] "/password_resets/$2a$10$oHhCh6ebtFXLYBKecGsTAu%2FJDc.3FuUKDVacUQTsbLKpiPR6IWTkK/edit"):
Route file looks like this:
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users
resources(:account_activations, { :only => [:edit] })
resources :password_resets, only: [:new, :create, :edit, :update]
end
Password Reset Controller
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update]
def new
end
def create
#user = User.find_by(email: params[:password_reset][:email].downcase)
if #user
#user.create_reset_digest
#user.send_password_reset_email
flash[:info] = "Email sent with password reset instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
def edit
end
def update
if password_blank?
flash.now[:danger] = "Password can't be blank"
render 'edit'
elsif #user.update_attributes(user_params)
log_in #user
flash[:success] = "Password has been reset."
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
# Returns true if password is blank.
def password_blank?
params[:user][:password].blank?
end
# Before filters
def get_user
#user = User.find_by(email: params[:email])
end
# Confirms a valid user.
def valid_user
unless (#user && #user.activated? &&
#user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
end
# Checks expiration of reset token.
def check_expiration
if #user.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
Finally the mailer url is set up like so:
<%= link_to "Reset Password", edit_password_reset_url(#user.reset_token, email: #user.email) %>
Routes
Prefix Verb URI Pattern Controller#Action
sessions_new GET /sessions/new(.:format) sessions#new
users_new GET /users/new(.:format) users#new
root GET / static_pages#home
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
signup GET /signup(.:format) users#new
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
logout DELETE /logout(.: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
edit_account_activation GET /account_activations/:id/edit(.:format) account_activations#edit
password_resets POST /password_resets(.:format) password_resets#create
new_password_reset GET /password_resets/new(.:format) password_resets#new
edit_password_reset GET /password_resets/:id/edit(.:format) password_resets#edit
password_reset PATCH /password_resets/:id(.:format) password_resets#update
PUT /password_resets/:id(.:format) password_resets#update
Thanks guys figured out the issue. I wasn't updating the password reset digest attribute correctly in the user model.
Updated it correctly and seems to be working!
Something weird is happening and I don't know why.
When I use the helper <%= link_to "New game", new_game_path %>, my new game form does not submit.
But when I acesses the view typing the URL localhost:3000/games/new form works just well
Any idea how to solve that?
Thanks,
Here my rake routes
Prefix Verb URI Pattern Controller#Action
root GET / games#index
user_sessions GET /user_sessions(.:format) user_sessions#index
POST /user_sessions(.:format) user_sessions#create
new_user_session GET /user_sessions/new(.:format) user_sessions#new
edit_user_session GET /user_sessions/:id/edit(.:format) user_sessions#edit
user_session GET /user_sessions/:id(.:format) user_sessions#show
PATCH /user_sessions/:id(.:format) user_sessions#update
PUT /user_sessions/:id(.:format) user_sessions#update
DELETE /user_sessions/:id(.:format) user_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
delete_progress_progresses POST /progresses/delete_progress(.:format) progresses#delete_progress
progresses POST /progresses(.:format) progresses#create
search GET /search(.:format) games#search
game_levels GET /games/:game_id/levels(.:format) levels#index
POST /games/:game_id/levels(.:format) levels#create
new_game_level GET /games/:game_id/levels/new(.:format) levels#new
edit_game_level GET /games/:game_id/levels/:id/edit(.:format) levels#edit
game_level GET /games/:game_id/levels/:id(.:format) levels#show
PATCH /games/:game_id/levels/:id(.:format) levels#update
PUT /games/:game_id/levels/:id(.:format) levels#update
DELETE /games/:game_id/levels/:id(.:format) levels#destroy
insert_levels_game POST /games/:id/insert_levels(.:format) games#insert_levels
games GET /games(.:format) games#index
POST /games(.:format) games#create
new_game GET /games/new(.:format) games#new
edit_game GET /games/:id/edit(.:format) games#edit
game GET /games/:id(.:format) games#show
PATCH /games/:id(.:format) games#update
PUT /games/:id(.:format) games#update
DELETE /games/:id(.:format) games#destroy
login GET /login(.:format) user_sessions#new
logout POST /logout(.:format) user_sessions#destroy
My route file
Rails.application.routes.draw do
root :to => 'games#index'
resources :user_sessions
resources :users
resources :progresses, :only => :create do
collection do
post 'delete_progress'
end
end
get 'search' => 'games#search'
resources :games do
resources :levels
member do
post 'insert_levels'
end
end
get 'login' => 'user_sessions#new', :as => :login
post 'logout' => 'user_sessions#destroy', :as => :logout
end
Sure, you can use string as relative URL. This will never crash since rails will not try to resolve your routes building it. My guess is, that you might have a typo of some sort.
There is no reason why this wouldn't work. I have searched your git app for "new_game_path" but could not find a single example where you use this code.
I have only found < a href="/games/new">New game</a> in your layout.
Replace it with <%= link_to 'New Game', new_game_path %> this works in your app. I have just tested it.
If you intend to use internationalization at some point, you should avoid standard HTML links. They will not keep your locale persistent.
form
You mention that your "form does not submit"
This is not a problem with your link_to - it's an issue with your form; they are two different issues:
--
link_to
link_to takes you to a new page. It's a helper method to help create the equivalent of Your text
This means that if you're sending requests to your new action, it should not matter how the users get there - only how the action is rendered.
The typical case for a form is as follows:
#app/views/games/new.html.erb
<%= form_for #game do |f| %>
<%= f.text_field :attribute %>
<%= f.submit "test" %>
<% end %>
#app/controllers/games_controller.rb
Class GamesController < ApplicationController
def new
#game = Game.new
end
end
--
Fix
When you mention your new game form does not submit, that's an issue with your form itself. This could be due to a number of reasons, but typically with the way in which you're rendering the form
To fix this, you'll need to detail how you're rendering your form & how you'd like it to submit
Update
Having read your updated comments, if the form works when you send the requests to the "naked" url, the issue may not be with the form itself.
As a rule of thumb, you'll always want to use the Rails helpers when defining links etc. In your application layout, I found that you posted "pure" HTML to create a link. This is bad because if the Rails syntax changes, or your routes change, your application won't update correctly.
Ive been following some rails guides and im trying to now implement something on my own for a project im doing and have hit a snag at the first hurdle
I get this error when trying to load the page
ActionController::UrlGenerationError in StepOne#login
Showing /Users/rogan/Sites/authImp/app/views/step_one/login.html.erb where line #3 raised:
No route matches {:action=>"show", :controller=>"step_one"} missing required keys: [:id]
Extracted source (around line #3):
<%= form_for url: step_one_path do %>
form stuff...
then my step_one_controller.rb
class StepOneController < ApplicationController
def new
end
def create
user = User.authenticate(params[:email], params[:password])
if user
pincode = generatePin
puts "one use pin.#{pincode}"
redirect_to "step_two"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
end
this was adapter from a login system i saw in a guide that used SessionsController.rb and form_for url: sessions_path
but my simple changes seem to have broke it, i've looked at my routes as well and they all seem to be in order
edit: heres is my routes
edit edit: changed everything to step_one and to removed the 's' as suggested, I now get
NoMethodError in StepOne#login
undefined method `model_name' for Hash:Class
<%= form_for url: step_one_path do %>
so from one problem to another!
AuthImp::Application.routes.draw do
resources :users
resources :sessions
resource :step_one
get "users/:id" => "users#show"
get "sign_up" => "users#new"
get "log_in" => "step_one#login"
get "step_two" => "sessions#new"
get "log_out" => "sessions#destroy", :as => "log_out"
then my rake routes is as follows
root to: "welcome#index"
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
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
step_one POST /step_one(.:format) step_ones#create
new_step_one GET /step_one/new(.:format) step_ones#new
edit_step_one GET /step_one/edit(.:format) step_ones#edit
GET /step_one(.:format) step_ones#show
PATCH /step_one(.:format) step_ones#update
PUT /step_one(.:format) step_ones#update
DELETE /step_one(.:format) step_ones#destroy
GET /users/:id(.:format) users#show
sign_up GET /sign_up(.:format) users#new
log_in GET /log_in(.:format) step_one#login
step_two GET /step_two(.:format) sessions#new
log_out GET /log_out(.:format) sessions#destroy
root GET / welcome#index
your problem is in the naming I think, resources :step_one assumes that you define the StepOnesController (plural), not StepOneController
So, you should either rename your controller or use resource :step_one route (without the s at the end)
It looks like Rails is expecting you to pass in an id to your step_one_path, so the form_for should look like this:
<%= form_for url: step_one_path(#user.id) do %>
Where #user.id would be the id of the user that the form is associated with. Hope that helps. If not, please include your routes.rb file.
<%= form_tag step_one_path do |f| %>
was the form tag necessary, i was going about it wrong
thanks for all the help
In rails how do I do a link_to a user show page of the current user. Basically i want a link that go to a account page.
I tried it but i get this.
Routing Error No route matches {:action=>"show", :controller=>"users"}
Routes.rb
LootApp::Application.routes.draw do
get "password_resets/new"
get "sessions/new"
get "static_pages/home"
get "static_pages/help"
resources :sessions
resources :password_resets
resources :email_activations
resources :users do
collection do
get :accept_invitation
end
end
root to: 'static_pages#home'
match "sign_up", to: "users#new"
match '/help', to: 'static_pages#help'
match '/log_in', to: 'sessions#new'
match '/log_out', to: 'sessions#destroy'
Application.html.haml
- if current_user
= link_to "log out", log_out_path
- if current_user.admin?
# your admin
- else
= link_to "My account", user_path
- else
= link_to "log in", log_in_path
Users controller
class UsersController < ApplicationController
before_filter :admin_and_user, only: [:destory, :edit, :show]
def show
#user = User.find(params[:id])
end
rake routes
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
just
<%= link_to current_user.name, current_user%>
The current answer is the best solution, but just to elaborate: The problem that was causing an error in your code was that you needed to specify which user the link should link to. So instead of just user_path should you do like this:
= link_to "My account", user_path(current_user)
A shortcut for this is (as shown in the current answer by #Muntasim)
= link_to "My account", current_user