Using Bootstrap with Bcrypt sessions form in Rails - ruby-on-rails

I'm using Bcrypt and has_secure_password for user authentications in a basic Rails app. For all of my other forms in the app I'm using the gem bootstrap_form which enables me to have nice looking bootstrap forms rather than the ugly default ones.
The problem is that Bcrypt doesn't seem to allow this for the sessions login form. It would be really good if I were able to integrate Bootstrap into this login form so that I don't need to play around with css for a long time.
My sessions/new.erb looks like this:
<%= form_tag sessions_path do %>
<h3>Log In</h3>
<div class="form-group">
<%= text_field_tag :email, params[:email], placeholder: 'Email',
:class => 'class_name' %>
</div>
<div class="field">
<%= password_field_tag :password, params[:password], placeholder:
'password', :class => 'class_name' %><br>
<%= link_to 'Sign up', new_user_path %>
</div><br>
<div class="actions"><%= submit_tag "Log In" %></div>
<% end %>
And my sessions controller looks like this:
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to new_comment_path, notice: "Logged in!"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
Thanks :-)

Gem Documentation LINK
But you'r probably doing
<%= bootstrap_form_tag sessions_path do %>,
instead of
<%= bootstrap_form_tag url: sessions_path do |f| %>
Answer: Try like this
<%= bootstrap_form_tag url: sessions_path do |f| %>
<%= f.email_field :email %>
<%= f.password_field :password %>
<%= f.check_box :remember_me %>
<%= f.submit "Log In" %>
<% end %>

Related

Rails not displaying error messages when submitting a form

I'm new to rails so I have a Signup controller that looks as follows:
class SignupController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to root_path, notice: "You are logged in as #{#user[:username]}"
else
puts #user.errors.full_messages
render :new
end
end
private
def user_params
puts params
params.require(:user).permit(:email, :password, :password_confirmation, :username)
end
end
So I'm trying to create a new user when I submit the form and my routes.rb file contains the following:
Rails.application.routes.draw do
root to: "home#index"
get '/about-us', to: "about#index", as: :about
# signing up
get 'sign_up', to: "signup#new"
post 'sign_up', to: "signup#create"
end
My app/views/signup/new.html.erb file has the following code in it:
<h1>Sign Up</h1>
<%= form_with model: #user, url: sign_up_path do |form| %>
<%= #user.errors.full_messages.inspect %>
<% if #user.errors.any? %>
<div class="alert alert-danger">
<% #user.errors.full_messages.each do |message| %>
<div><%= message %></div>
<% end %>
</div>
<% end %>
<div class="mb-3">
<%= form.label :email, class: "form-label"%>
<%= form.text_field :email, placeholder: "email#gmail.com", class: "form-control"%>
</div>
<div class="mb-3">
<%= form.label :username, class: "form-label"%>
<%= form.text_field :username, placeholder: "username", class: "form-control"%>
</div>
<div class="mb-3">
<%= form.label :password, class: "form-label"%>
<%= form.password_field :password, placeholder: "password", class: "form-control"%>
<div class="mb-3">
<%= form.label :password_confirmation, class: "form-label"%>
<%= form.password_field :password_confirmation, placeholder: "password", class: "form-control"%>
</div>
<div class="mb-3">
<%= form.submit "Sign Up", class: 'btn btn-primary'%>
</div>
<% end %>
But it seems like I'm getting the error messages in the console but they can't be rendered in the template when i submit the form with errors. Here is the errors i'm getting:
Password can't be blank
Email can't be blank
Email invalid email address
Username can't be blank
What maybe possibly the problem with my code here.
In your form, try this instead
<% if #user.errors.any? %>
<div class="alert alert-danger">
<% #user.errors.each do |error| %>
<div><%= error.full_message %></div>
<% end %>
</div>
<% end %>
I was using rails version 7.* so I manage to solve this error by changing the create method in the SignupController to :
def create
#user = User.new(user_params)
if #user.save
redirect_to root_path, notice: "You are logged in as #{#user[:username]}"
else
puts #user.errors.full_messages
render :new, status: :unprocessable_entity, content_type: "text/html"
end
end
This is according to the suggestions i got from Alex in the comments together with the discussion that i found here.

Why isn't my Create Form working, or even responding?

So I'm using form_with, and my code is placed in views/users/new.html.erb
<% content_for :title, "Sign Up" %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#user.errors.count, "error") %>
prohibited this user from being saved:
</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form_with model: #user do |f| %>
<%= f.label :email %>
<%= f.email_field :email, :placeholder => 'E-mail address' %><br>
<%= f.label :password %>
<%= f.password_field :password, :placeholder => 'Password' %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, :placeholder => 'Password confirmation' %><br>
<label>Are you a cleaner or customer?</label>
<%= f.select :user, User::SUB_CLASSES, include_blank: true %><br>
<%= f.submit "Next" %>
<% end %>
My controller has the following code
def new
#user = User.new
render :layout => "beforelogin"
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
if #user.sub_class == "Cleaner"
redirect_to new_cleaner_path
else
redirect_to new_customer_path
end
else
render :new
flash[:alert] = "Your registration could not be completed"
end
end
Now when I fill out the form on the user/new.html.erb route, nothing happens. The button just clicks. No errors pop up. I even tried to add to the top of the form, <%= form_with model: #user, url: users_path, method: "post" do |f| %>. Still the same response.
By default form_with attaches the data-remote attribute to the form. As a consequence, the form will be submitted using Ajax.
In case you want to disable this feature, you need to set the option local to true.
like this:
<%= form_with model: #user, local: true do |f| %>

integrating a homemade captcha to sign up and sign in?

So I have a basic sign up, sign in site with username and password. I don't want to use recaptcha and was wondering whether i can create my own?
So have for example 'what colour is an orange'.
I was wondering how you could integrate this (if you can that is) into the form_for as it wouldn't be part of the #user object and throws an error.
Here is the controller
def new
#user = User.new
#captcha = Captcha.find(rand(1..3))
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to root_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:username, :password, :release_pin)
end
Here is the view
<div class="sign-in-form">
<%= form_for #user do |form| %>
<div class="form-text">
<%= form.label :username %> <br>
<%= form.text_field :username %>
</div>
<br>
<div class="form-text">
<%= form.label :password %> <br>
<%= form.text_field :password %>
</div>
<br>
############## this here obviously throws
an error but this is the kind of thing i would want #########
<div class="form-text">
<p> <%=#captcha.question%> </p>
<%= form.text_field :captcha_answer %>
</div>
<div class="form-text">
<%= form.submit "Submit" %>
</div>
I've looked into nested forms but don't think that's the correct answer... but I could wrong as I'm only a beginner. thanks

Pass Reset - No route matches [PATCH] "/password_resets.SOLceKJXoax55zSBAfAhTQ"

I'm doing the Michael Hartl rails tutorial and trying to implement the password reset functionality but the request that sends the password reset form (The form where you reset your password) looks like /password_resets.SOLceKJXoax55zSBAfAhTQ which rails then says: No route matches [PATCH] "/password_resets.SOLceKJXoax55zSBAfAhTQ" In the tutorial we are asked to use this route: resources :password_resets, only: [:new, :create, :edit, :update] But I get that error message.
This is how my password_resets_controller.rb update method looks like:
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
Any idea how does my method or my route is causing that error?
Thank you in advance.
Update:
Adding my Reset Password view (password_resets\edit.html.erb)
<% provide(:title, 'Reset Password') %>
<h1>Reset Password</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user, url: password_resets_path(params[:id])) do |f| %>
<%= render 'shared/error_messages' %>
<%= hidden_field_tag :uemail, #user.uemail %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "update password", class: "btn btn-primary" %>
<% end %>
</div>
</div>
Change this:
<%= form_for(#user, url: password_resets_path(params[:id])) do |f| %>
to this:
<%= form_for(#user, url: password_reset_path(params[:id])) do |f| %>

Storing session variable after login in Rails 4

I already implemented from scratch (not using Devise or any other gem) a simple login form. Just Sign In, not Sign Up.
My concern here is about setting a variable that will be used the entire session the user is logged in. I already know that session variable could be set like this session[:user_id] = #user.id in controller, but I would like to add a shop variable (for example, shop_number ) This need to be set by the user himself (with a another form perhaps) after user is logged in, before any other action.
What is the best practice to do so? I was planning to use multistep forms, not sure is the best idea in this situation.
Here it is my controller:
class SessionsController < ApplicationController
def new
end
def create
#user = User.find_by_nom(params[:session][:NOM])
if #user && #user.authenticate(params[:session][:password])
session[:user_id] = #user.id
redirect_to '/'
else
flash[:alert] = "Usuario o contraseña incorrectos"
redirect_to '/login'
end
end
def destroy
session[:user_id] = nil
redirect_to '/'
end
end
And here it is my view:
<%= form_for(:session, url: login_path) do |f| %>
<h1>Login</h1>
<div class="form-inputs">
<%= f.label :Usuario %>
<%= f.text_field :NOM, placeholder: "Usuario", class: "form-control", label: 'Usuario' %>
<%= f.label :Contraseña %>
<%= f.password_field :password, placeholder: "Contraseña", class: "form-control", label: 'Contraseña' %>
</div>
<p>
<div class="form-actions">
<%= f.submit "Log in", class: "btn btn-primary" %>
</div>
<% end %>

Resources