Error on User Authentication not working - ruby-on-rails

I have a sessions_helper file that finds a user and if the user is found logins to the application. However, if the user is not found, it should give an error.
module SessionsHelper
# Log a user in after authenticating, store in session
def log_in(user)
if user.id.nil?
format.html { redirect_to signin_path, notice: 'Invalid Email or password' }
format.json { head :no_content }
else
session[:user_id] = user.id
end
end
end
I have a sessions/unauth view.
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">Log In!</div>
<div class="panel-body">
<%= form_for(:credentials, url: signin_path) do |f| %>
<div class="form-group">
<%= f.label :email%>
<%= f.email_field :email, class: 'form-control'%>
</div>
<div class="form-group">
<%= f.label :password%>
<%= f.password_field :password, class: 'form-control'%>
</div>
<%= submit_tag %>
<% end %>
</div>
</div>
</div>
This code allows user to login to app successfully, but if user is not found does not display an error on the application.

you need to include this into your view
<% if flash[:notice] %>
<div class="notice"><%= flash[:notice] %></div>
<% end %>
this code will display your error message.
read here

You've not published the flash message in the view.
--
Flash
The Rails Flash is a type of session variable used to store data generated in actions. It's means to give you the ability to call alerts / notices in either the view or layout.
There are 3 types of flash, although I think you can use as many as you wish:
notice
alert
error
When you call ... notice: 'Invalid Email or password' }, you're telling rails to populate the flash[:notice] object.
If you want to show this in your view, you need to invoke it, as following:
<div class="col-md-4">
<div class="panel panel-default">
<!-- Error -->
<%= flash[:notice] if flash[:notice] %>
<!-- Login -->
<div class="panel-heading">Log In!</div>
<div class="panel-body">
<%= form_for(:credentials, url: signin_path) do |f| %>
<div class="form-group">
<%= f.label :email%>
<%= f.email_field :email, class: 'form-control'%>
</div>
<div class="form-group">
<%= f.label :password%>
<%= f.password_field :password, class: 'form-control'%>
</div>
<%= submit_tag %>
<% end %>
</div>
</div>
</div>

Related

Failed to redirect from login_page to home page using devise

Hope you all are doing well. Actually i am facing an issue regarding redirect of my application from one page to another page.
Here is my sessions controller:-
```class Users::SessionsController < Devise::SessionsController
def new
#user=User.new
end
def create
#user=User.find_by(email: params[:email])
if user.present? && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to home_path, notice: "Logged in Successfully"
else
flash[:alert] = "Invalid Email or Password"
render :new
end
end
def destroy
session[:user_id] = nil
redirect_to root_path, notice: "Logged Out"
end
end```
My session view
```<div class="container py-5">
<!-- Outer Row -->
<div class="row justify-content-center">
<div class="col-xl-10 col-lg-12 col-md-9">
<div class="card o-hidden border-0 shadow-lg my-5">
<div class="card-body p-0">
<!-- Nested Row within Card Body -->
<div class="row">
<div class="col-lg-6 d-none d-lg-block bg-login-image"></div>
<div class="col-lg-6">
<div class="p-5">
<div class="text-center">
<h1 class="h4 text-gray-900 mb-4">Log In!</h1>
</div>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="form-group">
<%= f.email_field :email, autofocus: true, autocomplete: "email", class:"form-control form-control-user", placeholder:"Enter Email Address..." %>
</div>
<div class="form-group">
<%= f.password_field :password, autofocus: true, autocomplete: "current-password", class:"form-control form-control-user", placeholder:"Please Enter Password" %> </div>
</div>
<div class="check1">
<div class="form-group">
<% if devise_mapping.rememberable? %>
<div class="form-group">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end %>
</div>
<div class="actions">
<%= f.submit "Log in", class:"btn btn-primary btn-user"%><br>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>```
def create
#user=User.find_by(email: params[:email])
if users.present? && users.authenticate(params[:password])
session[:user_id] = user.id
redirect_to home_path, notice: "Logged in Successfully"
else
In this last error code i am facing issue in 3rd line user.present? line.
Please help me in this it's been 2 days am working on this issue but no working
You don't need to override Devise::SessionsController in your case. Just remove
controllers: { sessions: 'users/sessions' }
from your routes. Should be just:
devise_for :users
And add after_sign_in_path_for to your ApplicationController controller
class ApplicationController < ActionController::Base
def after_sign_in_path_for(*)
home_path
end
end

Request denied while updating user details in rails

I'm new to ruby on rails.
I've two type of users Admin and User. Admin can create edit and destroy user. I've no problem with create and destroy and have implemented quite easily.
I've used following code in controller,
private
def allowed_params
params.require(:user).permit(:role_id, :email, :password, :password_confirmation, :fname, :lname)
end
to define parameters required and allowed while creating user.
User Create
def save_user
#user = User.new(allowed_params)
if #user.save
redirect_to list_users_path
else
render 'add_user'
end
end
User Update
def update_user
#user = User.find(params[:id])
if #user.update_attributes(allowed_params)
redirect_to list_users_path
else
render 'edit_user'
end
end
View
<div class="container">
<div class="row">
<div class="col-md-12">
<%= link_to "Admin Dashboard", admin_dashboard_path, :class=>'pull-left' %>
<%= form_for #user, :url => update_user_path do |f| %>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<h2 style="text-align: center;">Edit User Details</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :fname, 'First Name' %><br />
<%= f.text_field :fname, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :fname) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :lname, 'Last Name' %><br />
<%= f.text_field :lname, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :lname) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :email, 'Email' %><br />
<%= f.text_field :email, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :email) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3" style="text-align: center">
<%= f.submit "Update User", :class => 'btn btn-sm btn-primary' %>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
when I pass only fname, lname and email nothing happened. I need to update user details what should I do here ?
Any suggestion is appreciated.
There is a debug way.
You should launch the server in development mode. Then check the changes of development.log file in the terminal by tail -f log/development.log.
Then do what you want, such as click the "submit" button when you changed the fname or other fields.
Then focus on the informations got on step 1. There are what you can get:
A. which Controller and action handled the request
B. The parameters of this request.
C. The log of SQLs excuted by DB
D. The response status
Check if the right Controller? or right parameters? or SQLs has been excuted? In addition, we used to #user.update_attributes!(allowed_params) when debug. It take more informations when something disobeys the rules defined in Model(User).

bootstrap modal for edit user profile

I have added bootstrap modal to edit user profile. It edits user profile but when there is an error in the form content it redirects to localhost:3000/user .how can I get errors in the modal itself? I used devise gem for user. what did I do wrong
_edit.html.erb
<div class="modal" id="EditProfileModal" data-keyboard="false" data-backdrop="static" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title">Edit user</h4>
</div>
<div class="modal-body">
<div class="container">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {method: :put}) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :email %><br/>
<%= f.email_field :email, autofocus: true, :value => current_user.email %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="form-group">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br/>
<%= f.password_field :password, autocomplete: "off" %>
<% if #minimum_password_length %>
<br/>
<em><%= #minimum_password_length %> characters minimum</em>
<% end %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %><br/>
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="form-group">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br/>
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: {confirm: "Are you sure?"}, method: :delete %></p>
</div>
</div>
<div class="modal-footer">
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
header
<% if user_signed_in? %>
<header>
<%= link_to "sign out", destroy_user_session_path, method: :delete %>
<%= link_to "Edit profile", '#EditProfileModal', {'data-toggle' => "modal"} %>
<div style="text-align: center">Signed in as <b><%= current_user.email %></b></div>
</header>
<%= render "devise/registrations/edit"%>
<% end %>
Form submission always forces a page reload. You can bypass this by submitting your form as ajax request. In Rails you can do this by passing option remote: true to your form_for call. Keep in mind, that to properly handle response from server you gonna need to handle javascript event:
$('[selector]').on('ajax:success', function(e, data, status, xhr) {
// do something
})
You need to use ajax for form submission with data-remote=true.
than you need to override the update action of registrations controller,
In the update action, you can check whether there is error or not with
if resource.update_attributes(your_params)
redirect_to :back # else any where you want to redirect
else
respond_to :js
end
and in registrations/update.js.erb you can add the div for show errors.
$(".modal-body").prepend("<div><%= resource.errors %></div>")

How to create an error message when users enter incorrect inputs on registration or form submission

I have two forms on my rails app that require a user to enter a code to confirm that they belong to a school and in the other form a code for a classroom. Every time a user enters or leaves the code blank I get this error message:
First argument in form cannot contain nil or be empty
It's always in the create method of the controller so I must not have the correct syntax.
Here are the two controllers where the error occurs.
Registration Controller
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :verify_authenticity_token, :only => :create
def update
super
end
def new
super
end
def create
code = params[:user][:code]
#school = School.where(:code => code).first
unless #school
flash[:error] = "School code not valid"
render :new
end
params[:user][:school_id] = #school.id
super
end
School controller
def create_teacher
authorize #school
params[:user][:school_id] = #school.id
params[:user][:role] = "teacher"
#teacher = User.create(teacher_params)
if #teacher.id.nil?
flash[:error] = #teacher.errors.full_messages
render :new_teacher
else
respond_with #school
end
end
How do I correct this issue so that it renders a flash error message?
EDIT Screen Shots of actual error. Note, they are both in the create method so I think it's an identical problem.
EDIT: Registration form for adding users to schools.
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h1>Sign up</h1>
</div>
<div class="panel-body">
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, autofocus: true, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :school_code %>
<%# f.text_field :code, class: "form-control" %>
<input type="text" id="code" name="user[code]" value>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
<strong>Student</strong> <%= f.radio_button(:role, "user") %>
<div class="form-group">
<%= f.submit "Sign up", class: "btn btn-lg btn-primary" %>
</div>
<% end %>
</div>
<div class="panel-footer">
<%= render "devise/shared/links" %>
</div>
I think the issue is with your <%= form_for .. %> I can get the same error if I enter an invalid argument for that. For the school one try <%= form_for #school %> And make sure your new method in your controller (whichever one is rendering the page with the form) is making a new instance of the object,
def new
#school = School.new
end
And the same with the pin
Something like this may be what you're looking for
before_action :check_code, only: :create
...
def check_code
unless School.find_by school_code params[:school_code]
flash[:error] = "Invalid school code"
redirect_to new_reg_path
end
end
And to show the flash message
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>">
<%= message %>
</div>
<% end %>

i have a form to create new users, but dont work

i have a problem with a form to create a user... this is my code of "new"
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<% for message in #user.errors.full_messages %>
<div class="alert">
<button type="button" class="close" data-dismiss="alert">×</button>
<%= message %>
</div>
<% end %>
<% end %>
<div class="field">
<%= f.label :username %>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit "Registrarse" %></div>
<% end %>
and "create" in controller
def create
#user = User.new(params[user])
if #user.save
redirect_back_or_to root_url, :notice => "Usuario Registrado Satisfactoriamente!"
else
render :new, :notice => "No se ha podido registrar"
end
end
when i create the user, this go to login form, and a receive a message empty, because i have an "if" if i have message, this show me a div with some css, so i can see that an error ocurred, but this come empty, what i have wrong? i dont see anything... and of course, the user is not created.!
thanks for the help, i am a newbie in ruby. and sorry for my bad english xd
The problem is that you most likely are referencing password_confirmation which is usually an input tag. You most likely do not have this field in your database as it would just be horrible practice. Are you salting your passwords?
Check out sorcery on github and the Railscasts. It does a nice job on covering authentication.
Also, you need to use :user in the params => User.new(params[:user])

Resources