How to show length validation error only if field is filled? - ruby-on-rails

I have validation like:
validates :description, presence: true, length: { minimum: 5, maximum: 500 }
Description can't be blank
Description is too short (minimum is 5 characters)
But, I want to show length validation error only if field is not left blank.
So, if user has not typed in the field, this error should show up:
Description can't be blank
And if user has inputted less than 5 character, this error should show up:
Description is too short (minimum is 5 characters)
Though, I just started learning RoR, it seemed to be little tricky. And I felt it will be even for others. So put this in SO. Have a look at my answer.

Ah, like this: (My boss replied)
validates :description, presence: true
validates :description, length: { minimum: 5, maximum: 500 }, allow_blank: true
I just needed to separate the presence validation and length validation. First it will check for its presence and then check for its length.

Related

Regex validation in rails

I am new with rails and I am trying to register my user's names without special characters and spaces but allowing the - symbol.
Example :
##Pierre! => invalid
Pierre-Louis => valid
Pierre Louis => invalid
In the User.rb file I have :
class User < ApplicationRecord
...
validates :first_name, presence: true, length: {maximum: 25}, format: {with: Regexp.new('[^0-9A-Za-z-]')}
...
I don't have any error message and I'm still able to register using special characters.
Also, I'd like to add an error message if the name isn't validated.
Do you have any leads ?
Any help would be much appreciated !
When you validate format with regex, you need to ensure you match the whole string that is being validated. In order to do that your regex needs to start with \A and end with \z that are anchors marking beginning and ending of the string.
In your case:
validates :first_name,
presence: true,
length: {maximum: 25},
format: {with: /\A[-0-9A-Za-z]\z'/}
message: "Custom message"
assuming you accept numbers, small and big letters and a minus sign.

How to not allow let users create passwords with space using ruby on rails?

I'm beginner to Ruby On Rails and I tried to do registration (name,email,password, confirming password) on my site (localhost) with restrictions like password can't be blank, password is at least 6 symbols long and password can't be like only spaces (" "). Then I want to let users edit these attributes but if they change it I want to make them write name and mail again but not password ( these 2 first are necessary, if they dont want to change it they leave them up, password is not necessarry so i want to make it blank, thats why in this code i use allow_blank: true)
# app/models/user.rb
.
.
.
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_blank: true
If I do it, users can register with spaces (" ") and it even allows them to break the rule with min 6 symbol ( users can do password like this: " " and I don't want this) so that's the problem.
But when I don't use allow_blank:true, when users want to edit their attributes they need to write again password ( I want to make them write only name and email but password can be left blank and it won't be changed then).
What should I do ?
Use a regular expression, through the without option of validates_format_of.
validates :password, presence: true,
length: { minimum: 6 },
format: { without: /\s/, message: "spaces not allowed" }
Okey I found the answer: instead of allow_blank: true I should have used allow_nil: true.

Cannot iterate over unique elements

I have an array of errors as below:
n.errors.full_messages
# => ["Password can't be blank", "Password can't be blank", "Password is too short (minimum is 3 characters)"]
I would like to iterate over the unique elements of this array and display them on the screen.
Validation model
class Member < ActiveRecord::Base
has_one :profile
before_save { self.username = username.downcase }
has_secure_password
validates :password, presence: true, length: { minimum: 3 }
end
n.errors.full_messages.uniq do |a|
puts a
end
uniq is not working, and "Password can't be blank" appears twice in my array. Any ideas?
Password can't be blank
Password can't be blank
Password is too short (minimum is 3 characters)
# => ["Password can't be blank"]
Edit: This doesn't actually answer the question, use the answer from #BroiSatse if google brought you here.
The reason you are getting that message twice is because of has_secure_password:
http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password
The first bullet point appears to add validation that makes the password required.
In your model you also add
validates :password, presence: true, length: { minimum: 3 }
The presence: true part of this adds the same validation. Remove this so its:
validates :password, length: { minimum: 3 }
This should fix the problem.
uniqe with a block uses value of the block to compare the elements. What you want is:
n.errors.full_messages.uniq.each do |m|
Anyhow, I think you're approaching the problem from the wrong angle - your problem is not how to avoid displaying duplicate messages, but how this duplication happened.
You could just do a string comparison.
Have the array that is problematic to you. Go over it and save the elements one by one to a new array.
Now when the first one is added to the new array, check that the elements allready in the array don't match the new element to be added. E.g: "My string".eql? "My sting"
There might be of course a more clever way to do this in Ruby. But that would be the idea when doing it in other languages manually.

rails 4 validates presence and length on the same parameter

Is it a good idea to having validates like this:
validates :serialnumber, presence: true, length: {7..20}, format: {with: /\d{7,20/}
As you see it generates three errors if I don't type serialnumber.
I would like to see only one error.
If I type nothing, I would like to see 'serial number is required' only.
If I type 123ABC I would like to see 'wrong length' only
And if I type 123-ABC-123 I would like to see 'wrong format' only
How to do it?
Regards
You could split it into 2 validators, check if this would work
validates :serialnumber, presence: true
validates :serialnumber, length: {7..20}, format: { with: /\d{7,20}/ }, allow_blank: true
As I understand then you want to see only one error message at a time. If that's the case then custom validation method might help. For ex.
validate :serial_number_validation_one_by_one
private
def serial_number_validation_one_by_one
if !self.serial_number.present?
errors.add(:serial_number, "must be present!")
elsif self.serial_number.length < 7 || self.serial_number.length > 20
errors.add(:serial_number, "must have length between 7 and 20!")
elsif self.serial_number.match(<your regex pattern here>)
errors.add(:serial_number, "must be properly formatted!")
end
end
Keep in mind that custom validation methods are called by validate not by validates.

How do I validate the length of a title in a rails app?

I'm learning Ruby on Rails right now and one of the exercises that I am trying to figure out is how to validate the title such that it has more than 10 characters. The hint says to use the :length method(?) in ruby.
So far I've tried:
validates :title.length, numericality: {greater_than_or_equal_to: 10}
and
validates :title, length: {greater_than_or_equal_to: 10}
both of which has given me errors.
What should I do here?
Another quick question, what is the difference when the colon(:) is on the left and right? for the length, it's on the left (:length), but for numericality, it's on the right (numericality:) I'm thinking if it's on the left it's a variable, and if it's on the right it's a method. Not sure if that's a good way to think of it.
Try:
validates :title, length: {minimum: 10}
To your second question:
key: value
is a hash syntax, which means the same as
:key => value
I'm not sure where you're being told to do it that way. The documentation is pretty specific:
validates :title, length: { minimum: 10 }

Resources