Rails password_reset recordnotfound - ruby-on-rails

I am getting an error when I pass in my url to reset my password for example: localhost:3000/password_reset/SADASIJDSIDJ1231231/edit <---- gives me ActiveRecord::RecordNotFound and its pointing at in my password_reset_controller
def edit
#user = User.find_by_password_reset_token!(params[:id])
end
This is my application controller (notice the "include SessionsHelper")
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
#om du lägger till kod här kmr inte sessions funka när du är inloggad wtf???
#tog bort detta protect_from_forgery with: :exception
include SessionsHelper
protect_from_forgery
private
def current_user
#current_user ||= User.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token]
end
helper_method :current_user
end
This is my password_reset_controller
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
user.send_password_reset if user
redirect_to root_url, :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.password_reset_sent_at < 2.hours.ago
redirect_to new_password_reset_path, :alert => "Password reset has expired."
elsif #user.update_attributes(params.permit![:user])
redirect_to root_url, :notice => "Password has been reset!"
else
render :edit
end
end
end
HOW I SOLVED IT:
So thanks to jorge I knew password_reset_token wasn't generated in the database. So I went back to my model/user.rb
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
I added back "save!" it was "save" before. Then I got another error saying password can't be blank.
So I deleted these two lines
# validates :password, length: { minimum: 6 }, presence: true
#validates :password_confirmation, presence: true
Instead I added this line
validates_presence_of :password, :on => :create
Now everything works. Thanks for your patience jorge. I owe u one big.

Did you check in the database that the a user exists with password reset token "SADASIJDSIDJ1231231"?
Looks like following line is not finding a user:
#user = User.find_by_password_reset_token!(params[:id])
Please include your User class - the send_password_reset method may not be saving the token correctly.

Related

Difficulty in implementing a one to one relationship

I am trying to update the profile of a user, however, I am getting an ArgumentError (wrong number of arguments (given 6, expected 1)): The relation between the user model and user profile model is one-to-one
application_controllers.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user, :logged_in?
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
def create
#user_profile = UserProfile.new(user_profile_params)
#user_profile.user_id = current_user.id
if #user_profile.save
format.html {redirect_to home_index_path, notice:"Account created successfully" }
else
flash.now.alert = "Oops, couldn't create account. Please make sure you are using a valid email and password and try again."
format.html { render :new }
end
end
private
def user_profile_params
params.require(:first_name, :other_name, :last_name, :phonemumber, :email, :seller_id)
end
Problem is on this line:
def user_profile_params
params.require(:first_name, :other_name, :last_name, :phonemumber, :email, :seller_id)
end
You should use either:
def user_profile_params
params.require(:user_profile).permit(:first_name, :other_name, :last_name, :phonemumber, :email, :seller_id)
end
or
def user_profile_params
params.permit(:first_name, :other_name, :last_name, :phonemumber, :email, :seller_id)
end
Depends on data you are getting from the form. And btw. there is a typo in :phonemumber should probably be :phonenumber.

helper functions are not working

users_controller.rb
class UsersController < ApplicationController
include UsersHelper
def new
#user = User.new
end
def create
if isUsernameTaken?
render 'new'
elsif isEmailTaken?
render 'new'
else
#user = User.new(user_params)
if #user.save
else
render 'new'
end
end
end
private
def user_params
params.require(:user).permit(:username,:email,:password,:password_confirmation)
end
end
users_helper.rb
module UsersHelper
def isUsernameTaken?
!(User.find_by(username: params[:username]).nil?)
end
def isEmailTaken?
!(User.find_by(email: params[:email]).nil?)
end
end
The problem is isUsernameTaken? or isEmailTaken? never gets executed and always the else part gets executed even if I give same username again. Why is this happening?
This is because params[:username] and params[:email] are always blank in your controller. They should be params[:user][:username] or user_params[:username].
Anyway, those kind of checks belongs to the model, not the controller and there already are validators to do exactly what you want:
class User < ActiveRecord::Base
validates :email, :username, uniqueness: true
end

NoMethodError: undefined method `password_reset_expired?' for nil:NilClass

I finished part of the Michael Hartl tutorial and I'm trying to add the password reset functionality (from Chapter 10) to my own app. I don't want the activation functionality, so I didn't add that. BUT I made sure to add the parts that were relevant to the Password Resets mailer (for example, the authenticated method).
When I run rake, here's what I get:
ERROR["test_password_resets", PasswordResetsTest, 2015-07-06 17:12:16 -0700]
test_password_resets#PasswordResetsTest (1436227936.11s)
NoMethodError: NoMethodError: undefined method `password_reset_expired?' for nil:NilClass
app/controllers/password_resets_controller.rb:60:in `check_expiration'
test/integration/password_resets_test.rb:26:in `block in <class:PasswordResetsTest>'
app/controllers/password_resets_controller.rb:60:in `check_expiration'
test/integration/password_resets_test.rb:26:in `block in <class:PasswordResetsTest>'
33/33: [=================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.10830s
33 tests, 83 assertions, 0 failures, 1 errors, 0 skips
Here's my Password Resets 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] = "An email was sent to " + #user.email + " with password reset instructions."
redirect_to login_url
else
flash.now[:danger] = "Hmm. We don't recognize that email. Make sure you signed up with this email."
render 'new'
end
end
def edit
end
def update
if params[:user][:password].empty?
flash.now[:danger] = "Uh oh. Your password can't be empty."
render 'edit'
elsif #user.update_attributes(user_params)
log_in #user
flash[:success] = "Success! Your password has been reset!"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
#BEFORE FILTERS
def get_user
#user = User.find_by(email: params[:email])
end
# Confirms a valid user.
def valid_user
if (#user && #user.authenticated?(:reset, params[:id]))
redirect_to root_url
puts("Either I don't exist or I'm not authenticated.")
end
end
# Checks expiration of reset token.
def check_expiration
if #user.password_reset_expired?
flash[:danger] = "Uh oh! Your password reset has expired. Please request a new password reset."
redirect_to new_password_reset_url
end
end
end
And here's my user model:
class User < ActiveRecord::Base
attr_accessor :remember_token, :reset_token
before_save { email.downcase! }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i #Set valid email regex to be used
validates :email, presence: true, length: { maximum: 255 }, format: {with: VALID_EMAIL_REGEX}, uniqueness: { case_sensitive: false}
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
#PASSWORD RESET
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
end
I've checked my spelling over, and over, and over, but it makes no difference even if I change the name of the function. What's happening?
By the way, when I physically try to use the password reset in localhost:3000, it says that a confirmation email was sent (but I don't receive one as I think that's part of localhost). Then when I visit the mailer preview, and use the reset password, it works fine. But in production (on Heroku), if I try to enter my email to get sent a confirmation email, I just get an error page - 500. Why would that happen?
Let me know if I need to add more details.
If your user is not found (eg there isn't a user with the given email)... what happens when you try to check the expiration of it?
Hint: look at what you do in valid_user for an example of what you should do in check_expiration

RoR - NoMethodError, undefined method

I have created an app with simple login authentication, it is actually a twitter clone. The user logs in and access the pages, etc.
But when the user posts something from there profile. It gives an error
NoMethodError in RibbitsController#create
undefined method `id=' for nil:NilClass
The error is around line 5:
class RibbitsController < ApplicationController
def create
#ribbit = Ribbit.create(user_ribbits)
#ribbit.userid = current_user.id
if #ribbit.save
redirect_to current_user
else
flash[:error] = "Problem!"
redirect_to current_user
end
end
private
def user_ribbits
params.require(:ribbit).permit(:content, :userid)
end
end
The request given to app:
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"dwVmjDNO4GOowphGFgChMDBxBfvka+M/xSUHvJMECzwxtv4NF6OuWtiaX74NLz91OwQJ9T9+wm7yMiPQ0BLpGA==",
"ribbit"=>{"content"=>"hi. test.\r\n"},
"commit"=>"Ribbit!"}
The sessions controller:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_username(params[:username])
if user && user.authenticate(params[:password])
session[:userid] = user.id
redirect_to rooturl, notice: "Logged in!"
else
flash[:error] = "Wrong Username or Password."
redirect_to root_url
end
end
def destroy
session[:userid] = nil
redirect_to root_url, notice: "Logged out."
end
end
The users controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.create(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to #user, notice: "Thank you for signing up!"
else
render 'new'
end
end
def show
#user = User.find(params[:id])
#ribbit = Ribbit.new
end
private
def user_params
params.require(:user).permit(:name, :username, :email, :password, :password_confirmation, :avatar_url)
end
end
And the application controller
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
I would really appreciate it if you guys would help!
Thanks.
You're trying to assign current_user.idto #ribbit.userid without ensuring that current_user is set. 'current_user' would be set only if a user has been previously saved before.
Therefore, you need either to make sure that an authenticated user is trying to create a Ribbit, or if you consider the userid as a non mandatory field, you can simply change your line 5 by:
#ribbit.userid = current_user.id unless current_user.blank?
If you only want authenticated user to create Ribbits, then consider using a gem to handle authentication such as Devise. You could then use before_filter :authenticate_user! in your controller to make sure users are properly authenticated.

action mailer rails ArgumentError in Password_resets#create

I set up a basic sign in, login, sign out format for a rails app and I was going to give it a function so that if a person forgot their password they could get a email back. when I went click on submit password reset I got
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
Extracted source (around line #3):
1: To reset your password click the URL below.
2:
3: <%= edit_password_reset_url(#user.password_reset_token) %>
4:
5: If you did not request your password to be reset please ignore this email and your password will stay as it is.
Rails.root: /Users/cheatermoves/nightclass/mainproject/project
Application Trace | Framework Trace | Full Trace
app/views/user_mailer/password_reset.text.erb:3:in `_app_views_user_mailer_password_reset_text_erb__3613112772785486465_70118994937040'
app/mailers/user_mailer.rb:6:in `password_reset'
app/models/user.rb:17:in `send_password_reset'
app/controllers/password_resets_controller.rb:7:in `create'
just completed rails cast 250 and was doing 274. Everything was fine until I got this problem.
here is my controllers. Password resets:
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
user.send_password_reset if user
redirect_to root_url, :notice => "Email sent with password reset instructions."
end
end
sessions:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
redirect_to root_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
def destroy
cookies.delete(:auth_token)
redirect_to root_url, :notice => "Logged out!"
end
end
users:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
session[:user_id] = #user.id
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
end
and application:
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
#current_user ||= User.find_by_auth_token( cookies[:auth_token]) if cookies[:auth_token]
end
helper_method :current_user
end
in environments/development.rb I have
config.action_mailer.default_url_options = { :host => "localhost:3000" }
here is my user model
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
validates_presence_of :password, :on => :create
before_create { generate_token(:auth_token) }
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
end
user_mailer.rb file
class UserMailer < ActionMailer::Base
default from: "from#example.com"
def password_reset(user)
#user = user
mail :to => user.email, :subject => "Password Reset"
end
end
anyone know what the problem is and how to fix it? I'm using rails 3.2.14 if anyone is wondering. Thanks!
Didn't read the part where you said that you already set your
config.default_url_options[:host] = "localhost:3000"
my bad, sorry

Resources