Something wrong with my validates in Rail 4? - ruby-on-rails

I want to show my validates in "users.rb". Can anyone help?. I've watched some video tutorial then found myself that was not "define new" but I did not know how to resolve this.
user_controller.rb
class UsersController::ApplicationController
def login
if params[:user]
#notice = "LOGIN FAILED"
#email = params[:user][:mailaddress]
#password = params[:user][:password]
#user = User.find_by(mailaddress: #email)
if #user
#member = Member.find_by(user_id: #user.id)
if #member
#hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), #member.salt, #password)
if #hash == #member.hashed_password
# SUCCESS
#notice = "LOGIN SUCCESSFULL"
end
end
end
end
end
end
-------
user.rb
class User::ActiveRecord::Base
has_one :member
validates :mailaddress, presence: {message: "Email need inputed"} #want to show this validates in login.html.haml
end
---------------
login.html.haml
= form_for(:user, url:login_path) do |f|
%div.login
= f.label "Email", class:'control-label'
= f.email_field :mailaddress, class: 'form-control'
= f.label "Password", class: 'control-label'
= f.password_field :password, class: 'control-label'
%div.btn-are
= f.submit 'Finish', class: 'btn'

Validations works only on model create/update but not on some actions like login.
Please see the docs for more info.
You can show flash if some params are missing
user_controller.rb
class UsersController::ApplicationController
def login
if params[:user]
unless params[:user][:mailaddress]
flash[:error] = "Email is required"
render :your_login_path
end
#notice = "LOGIN FAILED"
#email = params[:user][:mailaddress]
#password = params[:user][:password]
#user = User.find_by(mailaddress: #email)
if #user
#member = Member.find_by(user_id: #user.id)
if #member
#hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), #member.salt, #password)
if #hash == #member.hashed_password
# SUCCESS
#notice = "LOGIN SUCCESSFULL"
end
end
end
end
end
end
- flash.each do |name, msg|
= content_tag :div, msg, class: name
= form_for(:user, url:login_path) do |f|
%div.login
= f.label "Email", class:'control-label'
= f.email_field :mailaddress, class: 'form-control'
= f.label "Password", class: 'control-label'
= f.password_field :password, class: 'control-label'
%div.btn-are
= f.submit 'Finish', class: 'btn'
The code above is untested, but should work.
Here is the flash documentation
But I'm strongly recommend to use devise to perform sign_in/sign_up of users.

Related

Mail_form gem not showing error for invalid email

I have working mail_form contact form with google's smtp service.
I satisfied almost with everything, but form not showing errors for invalid email.
There is an error appears if email field is blank, but if something present in the field and you press "Send message" button nothing happens - validation not allowing send message, but user not informed that something wrong.
contact.rb
class Contact < MailForm::Base
attribute :name
attribute :email, validate: URI::MailTo::EMAIL_REGEXP
attribute :message, validate: true
attribute :file, attachment: true
def headers
{
subject: "My Contact Form",
to: 'MYEMAIL#gmail.com',
from: %("#{name}" <#{email}>)
}
end
end
views/contacts/new.html.haml
= form_with model: #contact do |f|
= f.label :name
= f.text_field :name, required: true, class: "text-field"
= f.label :email
= f.text_field :email, required: true, class: "text-field", placeholder: "email#example.com"
= f.label :message
= f.text_area :message, rows: 6, required: true, class: "text-field"
= f.label :files, class: "inline-block p-1 pt-2"
= f.file_field :file, class: "block p-1 font-body text-sm"
= f.submit t('send_message'), class: "submit"
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
#contact.request = request
if #contact.deliver
redirect_to contacts_path, notice: 'Message sent!'
else
flash.now[:error] = 'Could not send message'
render :new
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :message, :file)
end
end
I have tried many things to show error messages, which have worked in my previous projects, but can't make it work with mail_form contact form.

ruby form_for password field not submitted to params hash

Working through the ruby on rails tutorial from Hartl right now.
the password field is displaying weirdly, and when I submit some information I can see that my params hash doesn't display a password key (but displays everything else). What's going on?
views/users/new.html.erb:
<h1> Sign up </h1>
<div class = "row">
<div class = "col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control'%>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control'%>
<%= f.label :password %>
<%= password_field :password, class: 'form-control'%>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control'%>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
controllers/users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def new
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
end
models/user.rb
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX},
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
def User.new_token
SecureRandom.urlsafe_base64
end
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
def forget
update_attribute(:remember_digest, nil)
end
# Activates an account.
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
# Sets the password reset attributes.
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
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
private
def downcase_email
self.email = email.downcase
end
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
<%= password_field :password, class: 'form-control'%>
to
<%= f.password_field :password, class: 'form-control'%>

Unable to 'Sign In' or 'Sign Up' with authentication features (no Devise gem)

I am currently unable to Sign Up or Sign In a user through my application and I'm unable to figure out why. I am using nested parameters with my User/Profile models.
When I try to sign up a new user, I get proper flash message saying
"Invalid email or password".
I created my authentication from scratch (not using Devise!). I also have a 'forgot password'/'remember me' feature but I have not displayed that information below as I think it is irrelevant.
Here is the console log (it seems to be a rollback, but no specific error given):
{Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ek4cgnR3FQePCg/A4Wqc3atinU+WwRNgj+5hpXsd4mY=", "user"=>{"email"=>"sign#up.co", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "profile_attributes"=>{"first_name"=>"101001010", "last_name"=>"10101110101", "linkedin"=>"www.linkedin.com/signup", "twitter"=>"www.twitter.com/signup"}}, "commit"=>"Sign Up"}
(0.1ms) begin transaction
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'sign#up.co' LIMIT 1
(0.1ms) rollback transaction
Rendered users/new.html.haml within layouts/application (60.3ms)
Completed 200 OK in 158ms (Views: 75.9ms | ActiveRecord: 0.3ms)}
models/user.rb
class User < ActiveRecord::Base
...
has_one :profile
accepts_nested_attributes_for :profile
delegate :full_name, to: :profile
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
VALID_URL_REGEX = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9] {1,5})?(\/.*)?$/ix
validates :email, :uniqueness => true, :presence => true
validates :first_name, :presence => true, length: {minimum: 1}
validates :last_name, :presence => true, length: {minimum: 1}
validates :twitter, :format => { with: VALID_URL_REGEX, :multiline => true}
validates :linkedin, :format => { with: VALID_URL_REGEX, :multiline => true}
models/profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
def full_name
if first_name || last_name
"#{first_name} #{last_name}".squeeze(" ").strip
end
end
end
controllers/users_controller.rb
class UsersController < ApplicationController
def new
#user = User.new
#user.build_profile
end
def create
#user = User.new(user_attributes)
if #user.save && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, notice: "Thanks for signing in"
else
flash.now.alert = "Invalid email or password"
render :new
end
end
private
def user_attributes
params.require(:user).permit(:email, :password,
:password_confirmation,
{profile_attributes: [:first_name, :last_name, :linkedin, :twitter]})
end
end
controllers/profiles_controller.rb
class ProfilesController < ApplicationController
before_action :find_profile
def show
end
def update
if #profile.update_attributes(profile_params)
redirect_to posts_path
end
end
def edit
end
private
def profile_params
params.require(:profile).permit(:first_name, :last_name, :linkedin, :twitter)
end
def find_profile
#profile = current_user.profile
end
end
controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.find_by_email(params[:email])
respond_to do |format|
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
format.html { redirect_to root_path, notice: "You're logged in!" }
format.js do
flash.now.notice = "You're signed in!"
render
end
else
flash.now.alert = "Email or password is invalid"
format.html { render :new }
format.js { render :new }
end
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
Here are the views (haml)
views/user/new.html.haml
%h1 Sign Up for a New Account
= simple_form_for #user, html: { class: 'form-horizontal' } do |f|
.well
.container
= f.input :email, html_input: {class: "form-control"}
= f.input :password
= f.input :password_confirmation
= f.fields_for :profile do |p|
= p.input :first_name
= p.input :last_name
= p.input :linkedin
= p.input :twitter
= label_tag :remember_me
= check_box_tag :remember_me, 1, params[:remember_me]
= f.submit "Sign Up", class: "btn btn-primary"
**views/sessions/new.html.haml
%h1 Sign In
= simple_form_for "", url: sessions_path, html: {class: "form-horizontal"} do |f|
= f.input :email
= f.input :password
= f.submit "Sign In", class: "btn btn-primary"
%br
%p
=link_to "Forgot your password?", new_password_reset_path
%p
No account, yet?
= link_to "Sign up", signup_path
This problem has been bugging me for quite some time. I'd like to test out some of the user functionality but I cannot do so as I'm unable to login. Right now there is only one User record in the database and I created that manually in console. I am not able to log in to that user record either.
Any help is greatly appreciated.
def create
#user = User.new(user_attributes)
if #user.save && user.authenticate(params[:password])
session[:user_id] = user.id
...
end
In this code you create an instance variable (#user), but you call authenticate on user. You should either use User.authenticate or #user.authenticate (depending on how you implemented the authenticate method in your model). You should also change session[:user_id] = user.id to session[:user_id] = #user.id.

flash[:notice] displaying extra character

I'm having a strange issue where an extra/random character ("0") is being displayed with my flash[:notice]. I can't figure out where it's coming from.
Controller:
def edit
#subject = Subject.find_by(id: params[:id])
end
def update
#subject = Subject.find_by(id: params[:id])
if #subject.update_attributes(strong_params)
flash[:notice] = 'Subject has been updated'
redirect_to action: 'show', id: #subject.id
else
render 'edit'
end
end
def delete
#subject = Subject.find_by(id: params[:id])
end
private
def strong_params
params.require(:subject).permit(:name, :position, :visible)
end
View:
= if !flash[:notice].blank?
.notice
= flash[:notice]
%h2 Update subject
= form_for :subject, :url => {action: 'update', id: #subject.id} do |f|
= f.label :name, 'Name:'
= f.text_field :name
= f.label :position, 'Position:'
= f.text_field :position
= f.label :visible, 'Visible:'
= f.text_field :visible
= f.submit 'Update Subject'
%h2
Are you sure you want to delete the subject - #{#subject.name}
= link_to 'Yes, delete!', action: 'destroy', id: #subject.id
So, as it turned out the answer is: change 'loud' haml = if !flash[:notice].blank? to 'silent' - if !flash[:notice].blank?.

Creating sessions while user signs up in rails

HI ,
i have some doubts on sign up feature in rails application (2.3.10)
in my views/users/new.html.erb
<div id="signup_form" style="display:none;" class="login-drpdwn ">
<% form_for :user, :url => users_path do |f| -%>
<%= error_messages_for 'user' %><br/>
<div>
<p> Enter your name </p>
<%= f.text_field :name, :class => "text_box" %>
<p> Enter your login name </p>
<%= f.text_field :login, :class => "text_box" %>
<p> Email ID</p>
<%= f.text_field :email, :class => "text_box" %>
<p> Password</p>
<%= f.password_field :password, :class => "text_box" %>
<p> Confirm your password</p>
<%= f.password_field :password_confirmation, :class => "text_box" %>
<div class="textalign_right">
<input type="submit" value="Submit" class="submit_button rounded_corner"/>
</div>
</div>
<% end %>
</div>
In my Users controller
before_filter :login_required, :except => [:new, :create, :forgot, :reset, :process_forgot_password, :activate]
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to "/blogs/home",:notice => "signed up"
else
redirect_to "new"
end
end
In my User model
before_save :encrypt_password
attr_protected :id, :password_salt
attr_accessor :password, :password_confirmation
def self.authenticate(email, password)
user = find_by_email(email)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
In my sessions controller - create method
def create
#current_user = User.find_by_login(params[:login].downcase)
if #current_user.blank? || params[:password] != #current_user.password_hash
#current_user = nil
render :action => "new"
else
session[:user_id] = #current_user.id
session[:close_time] = 1800.seconds.from_now
if #current_user.last_login.nil?
#login = LastLogin.new
#login.user_id = #current_user.id
#login.login_at = Time.now
#login.save
else
#login = #current_user.last_login
#login.last_at = #login.login_at
#login.login_at = Time.now
#login.login_count += 1
#login.save
end
if session[:return_to]
redirect_to session[:return_to], :protocol => USE_PROTOCOL
session[:return_to] = nil
else
end
end
end
when i submit the sign up page the user is getting created but not the session
so its not directing to the blogs /home page as it has before_filter :login_required there in blogs controller..
how to resolve this
My code is not having include Authenticated system line
session[:id] = #current_user.id

Resources