I built a small Sinatra application that was working, but I added a confirm_password
in the signup form and made changes in user_controller
and broke something. Now, it is not letting the user login even after entering a valid username and password. It again takes them to login/signup page.
I tried debugging with binding.pry
, so I know that it is assigning session[:user_id]
to user.id
, but I'm not sure why it keeps asking for user credentials.
This is my migration for the user:
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
t.string :username
t.string :password_digest
t.string :email
t.timestamps
end
end
end
This is my user model:
class User < ActiveRecord::Base
has_secure_password
has_many :tips
has_many :languages, through: :tips
validates_presence_of :username, :email, :password_digest
validates_uniqueness_of :username, presence: {message: "That username is already taken, please use another username."}
validates_uniqueness_of :email, presence: {message: "That email is already associated to another account. Please use another email."}
include Slugifiable::InstanceMethods
extend Slugifiable::ClassMethods
end
This is my user_Controller:
class UserController < ApplicationController
get '/signup' do
if !logged_in?
erb :'users/signup'
else
redirect to '/tips'
end
end
post '/signup' do
# binding.pry
if params[:username] == "" || params[:password] == "" || params[:email] == "" || params[:confirm_password] == ""
redirect to '/signup'
# binding.pry
elsif params[:password] != params[:confirm_password]
erb :'users/password_error'
else
user = User.create(username: params[:username], password: params[:password], email: params[:email])
session[:user_id] = user.id
redirect to '/tips'
end
end
get '/login' do
if !logged_in?
erb :'users/login'
else
redirect to '/tips'
end
end
post '/login' do
# binding.pry
user = User.find_by(username: params[:username])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect to "#{user.username}/tips"
else
redirect to '/signup'
end
end
get '/logout' do
if logged_in?
session.clear
# binding.pry
redirect to '/login'
else
redirect to '/'
end
end
get '/users/:slug' do
if logged_in? && current_user.slug == params[:slug]
@user = User.find_by_slug(params[:slug])
erb :'/users/show'
else
redirect to '/tips'
end
end
end
I don't think my signup form is creating any issue, but for debugging purposes, here is my signup.erb form:
<h2 style="color: #66FFFF">Sign Up for the Coding Tips </h2></br> </br>
<form action="/signup" method="POST">
<p> Username: <input type="text" name="username" ></p>
<p> Email: <input type="email" name="email"></p>
<p> Password: <input type="password" name="password"></p>
<p> Confirm password: <input type="password" name="confirm_password"></p></br></br>
<input type="submit" value="Sign Up">
</form>
I am sure I am using a valid username and password. I tried creating a couple of new usernames, it also saves them to the database, but it doesn't let anyone login.
These are my helper methods:
def logged_in?
!!current_user
end
def current_user
@current_user ||= User.find(session[:id]) if session[:id]
end
Here is my tip_comtroller
class TipController < ApplicationController
use Rack::Flash
get '/:slug/tips' do
@user = User.find_with_slug(params[:slug])
if logged_in? && session[:user_id] == @user.id
erb :'/users/tips'
else
redirect to "/login"
end
end
get '/tips' do
erb :'/tips/tips'
end
get '/tips/new' do
if logged_in?
erb :'/tips/new'
else
redirect "/login"
end
end
post '/tips' do
@tip = current_user.tips.create(content: params[:content])
if @tip
if params[:language][:name].nil? || params[:language][:name].empty?
@tip.language_id = params[:tip][:language_id]
else
new_language = Language.create(name: params[:language][:name])
@tip.language_id = new_language.id
end
@tip.save
@user = @tip.user
redirect to "/tips/#{@tip.id}"
else
redirect "/tips/new"
end
end
get '/tips/:id' do
@id = params[:id]
if logged_in?
@tip = Tip.find_by_id(params[:id])
if !@tip.nil?
erb :'/tips/show'
else
erb :'/tips/show_error'
end
else
redirect "/login"
end
end
get '/tips/:id/edit' do
if logged_in?
@tip = Tip.find_by_id(params[:id])
if @tip.user.username == current_user.username
erb :'/tips/edit'
else
erb :'/tips/edit_error'
end
else
redirect "/login"
end
end
patch '/tips/:id' do
@tip = current_user.tips.find_by(params[:id])
if @tip
@tip.update(:content => params[:content])
if params[:language][:name].nil? || params[:language][:name].empty?
@tip.language_id = params[:tip][:language_id]
else
new_language = Language.create(name: params[:language][:name])
@tip.language_id = new_language.id
end
@user = @tip.user
@tip.save
# binding.pry
redirect "/tips/#{@tip.id}"
else
redirect "/tips/#{@tip.id}/edit"
end
end
get '/tips/:id/delete' do
@tip = Tip.find_by_id(params[:id])
if logged_in?
if current_user == @tip.user
@tip.destroy
redirect '/tips'
else
erb :'tips/delete_error'
end
else
redirect "/login"
end
end
get '/tips/:id/cancel' do
redirect "/tips/#{@tip.id}"
end
end
Your logged_in
function is using :id
instead of :user_id
:
def logged_in?
!!current_user
end
def current_user
@current_user ||= User.find(session[:id]) if session[:id]
end
Try changing it to this:
def logged_in?
!!current_user
end
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end