How to validate user input in RoR? - ruby-on-rails

I know that the RoR can do the validation in the models. But I want to confirm the user's password in the views. I means, it show two textfield for user to type password twice to ensure the user type the password correct, but in the database I only store one value. How can I handle it in the RoR?

In your model do:
validates_confirmation_of :password
In your view do:
<%= form.password_field :password %>
<%= form.password_field :password_confirmation %>
This is using the built in rails confirmation validation. It's will add the virtual accessor for you.

Related

Errors in model namespaces

I broke up my signup into an overall Signup model with multiple model namespaces (I believe these are what they are called) into separate files. For example,
Signup.rb
class ContractorSignup < ActiveRecord::Base
# It has fields of first_name, last_name, email, phone_number, address
end
In the signup folder there are these models
ContractorSignup::Personal < Signup
validates_presence_of :first_name, :last_name, :email, :phone_number
end
In the form I am using the main model
= form_for #contractor_signup, url: signup_step_path('email') do |form|
= form.label :first_name
= form.text_field :first_name
= form.submit "Next"
The form comes back responding to the correct validation but I cannot figure out how to grab the errors that it captures based on the validation.
This next is for a Rails wizard built duplicating this person's talk. http://www.codepainter.ca/2013/10/ultra-light-maintainable-wizards-in.html
If I do a #contractor_signup.errors.inspect I see no messages in #contractor_signup.errors.inspect when I am filling in a completely blank form. However, I found that if I submit a form with everything but first name, or last name filled out I receive a message in errors saying first_name []

Edit Devise email format

I am currently using devise for user registration and will like to restrict signups based on domains like #company.com or #work.com. The aim is for users to only provide the first part of their email address for example "lucy.dale" then select their domain from a drop-down menu such as #company.com. Please see the code I have generated so far..
<div><%= f.label :email %><br />
<%= f.text_field :first_email, :autofocus => true %><%= f.select :domain, options_for_select([["Select One", ""], "#company.com", "#work.com", "#office.com"]) %>
As i don't have access to the Devise controller or mailers, please can you advise me on how I can join the :first_email & :domain attributes to give (lucy.dale#company.com) before passing it to the default :email attribute in Devise.
Thanks for your help in advance
I hope this help someone out there. Instead of extending the devise registration controller, i decided to use a Regex to validate the domains. This will allow me restrict the domains as shown below
validates_format_of :email, :with => /\A([^#\s]+)#(company\.com)|(work\.com)\z/
The regex was added to the model for validation.

How to verify password exists using client_side_validations gem?

I have a change password form that requires a user to provide their current password. Using the client_side_validations gem, is it possible to verify that the current password is correct using a remote validator/javascript? If so, how?
app/views/passwords/new.html.haml
= simple_form_for #password_form, url: passwords_path, method: :post, validate: true do |f|
= f.input :original_password
= f.input :new_password
= f.input :new_password_confirmation, required: true
= f.submit 'Save'
app/forms/password_form.rb
...
attr_accessor :original_password, :new_password
validate :verify_original_password
validates_presence_of :original_password, :new_password
validates_confirmation_of :new_password
validates :new_password, password: true
def verify_original_password
unless #user.authenticate(original_password)
errors.add :original_password, "is not correct"
end
end
...
You can't validate password correctness client-side without passing the client an enormous list of all the (presumably) hashed passwords in your DB. This is computationally not really feasible, but even worse you would be exposing a list of all your users' hashed passwords! It wouldn't be hard for a hacker to break open at least a few of these (I've heard stories of people decrypting >80% of a list of MD5 hashed passwords in <1 hour).
So you'll have to speak to the server to verify a password.

Validate field is unique compared to another field in same form

Say I have two fields in a new or edit form:
<%= f.text_field :email %>
<%= f.text_field :parent_email %>
How, in my model, can I validate that parent_email is different from email? The exclusion option seems like it might work, but I can't figure out how to access the email field's value within the model. Do I need to implement this in the controller instead?
validates :parent_email, exclusion: self.email # doesn't work, nor does :email
The following should work (but I guess there are cooler solutions out there):
class User
validate :email_differs_from_parent_email
private
def email_differs_from_parent_email
if email == parent_email
errors.add(:parent_email, "parent_email must differ from email")
end
end
end

Rails Model: How to make an attribute protected once it's created?

I was just wondering: How can i make an attribute "write once" ?
To be more precise, I'm using Devise and I want the user to be able to register with this email but then, once it's done, I want this email locked.
I read that forms can easily be bypass, so I want to make sure my model does that.
Also, i'm using in one of my form that: <%= f.email_field :email, :id => "email", :disabled => "disabled" %>
Is there any risks that an user can modify his email after being registered?
Thanks for your answers!
attr_readonly allows setting a value at creation time, then prevents modifying it on updates.
class MyModel < ActiveRecord::Base
attr_readonly :email
end

Resources