Model Validation not working in rails 4 - ruby-on-rails

I don't know why, but I am stuck with a simple issue. I have a simple User model and I have given a simple validation to one of its field ie., username for presence and its length.
Below is the code:
user.rb
class User < ActiveRecord::Base
validates :username, presence: true, length: { minumum: 3, maximum: 25 }
end
Accordingly,
user = User.new(username: 'hi')
user.save
must fail as the length of the username (i.e., is too short as per the validation given). But in my case it is getting saved without any errors. Currently it is only giving errors when username is blank but not giving errors for min length. Note: I have reload! my rails console

You have misspelled minimum :) Try this:
class User < ActiveRecord::Base
validates :username, presence: true, length: { minimum: 3, maximum: 25 }
end
Also, re: the answer below, this is directly from the RailsGuides for Active Record Validations:
class Essay < ActiveRecord::Base
validates :content, length: {
minimum: 300,
maximum: 400,
tokenizer: lambda { |str| str.split(/\s+/) },
too_short: "must have at least %{count} words",
too_long: "must have at most %{count} words"
}
end

Related

how to reuse same set of validations on different columns and different models

We have same set of validations on different fields.
we have fee columns. with the following validations
validates :sytem_fee, presence: true,
format: { with: fee_regex, message: format_error_message },
numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 40 }
validates :sytem_discounted_fee, presence: true,
format: { with: fee_regex, message: format_error_message },
numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 40 }
The set of validations applied to the columns is basically the same.
we have also the fees in different models. They have the same validations basicaly.
I know that there are custom validators like: EmailValidator < ActiveModel::EachValidator
My question is: can we create a custom validator that uses the default validations like presence, numericallity and so on?
The idea is to be able to say validates some_fee, percent_fee_column: truein any model
You can put your method in the app/models/concerns folder, for example, as Validatable module (i.e. validatable.rb):
module Concerns::Validatable
extend ActiveSupport::Concern
def format_website
if website.blank?
self.website = nil
elsif !self.website[/^https?/]
self.website = "http://#{self.website}"
end
end
end
And then include it in each models as
include Concerns::Validatable

Validate last letters of input field in Rails

How would I validate the last letters of a link which is posted into my model?
Example:
[dropbox.com/dajnkqjknw7/file.mp3]
[dropbox.com/dajnkqjknw7/file.ogg]
[dropbox.com/dajnkqjknw7/file.wav]
I just want to check/validate if the last 3 (or 4) letters end on .mp3, .ogg or .wav, how would I use that within my model, use a Regex in combination with validates?
Current beat.rb model:
class Beat < ApplicationRecord
validates :bpm, format: { with: /\A\d+\z/ }, length: { maximum: 3 }
validates :link, presence: true REGEX IN HERE?
end
You can use something like this
validates :link, presence: true, format: { with: /.(mp3|ogv|wav)\z/}
where you have a dot . and after one of the valid extensions (mp3|ogv|wav), just at the end of the line \z

Comparing database fields/columns with each other inside validations in Ruby on Rails

I have the following model in Rails which manages a Diabetes Settings table:
class DiabetesSetting < ApplicationRecord
belongs_to :user
validates :bs_min, :bs_max, :bs_target, :correction_number, numericality: { only_integer: true }
validates :correction_insulin, numericality: true
validates :bs_min {less_than: :bs_max }
validates :bs_max {greater_than: :bs_min}
validates :bs_target {less_than: :bs_max}
end
My Question: Is something like this, to compare the fields of a database with each other to validate, that when a new setting is created, one value is higher or lower than the other, possible in Rails or do I have to write custom validation methods for this?
To clarify: bs_min is the mimmum value of a numerical range and bs_max the max value of a numerical range. They are both attributes inside the diabetes settings model.
The Question is if I can compare these values like I did or if I have to write custom methods to validate
Thanks in advance for Your help
You can do it using Rail's built-in validations. Try below code:
class DiabetesSetting < ApplicationRecord
...
validates_numericality_of :bs_min, { less_than: :bs_max }
validates_numericality_of :bs_max, { greater_than: :bs_min }
validates_numericality_of :bs_target, { less_than: :bs_max }
end
Refer to following link for numerical validation: http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_numericality_of
Ruby on Rails 7.0 added support for validates_comparison_of validations like this
validates :bs_min, comparison: { less_than: :bs_max }
validates :bs_max, comparison: { greater_than: :bs_min }
validates :bs_target, comparison: { less_than: :bs_max }

How to customize the validations in rails if the request comes from specific controller?

lets say that I want to make the possibility of posting two types of posts [long] and [short] sharing the same table [id, title, content, short:boolean, user_id] and model
and the user chose to post short post and the site only will store the content and it will be under 120 char, to recognize it we will put the short:true, but how to customize the validations if it chose short to allow empty title and content under 120 char ..... etc
Simplest way to solve your problem is conditional validations. Your model should be like this:
class Post < ActiveRecord::Base
validates :title, presence: true, unless: :short?
validates :title, absence: true, if: :short?
validates :content, presence: true
validates :content, length: { maximum: 120 }, if: :short?
end
I'm not sure i understood all conditions in your example right, hope this code is enough to make what you want.
Also you may read details about conditional validations in Rails documentation.
Since you have a short boolean field on Post, you can simply add these helper methods
class Post < AR
# this method is automatically generated by rails
def short?
short
end
def long?
!short
end
end
And then add if: or unless: to your validations:
validates :content, length: { maximum: 120 }, if: :short?
validates :content, presence: true, if: :long?

How to validate bank details like account_number, ifsc_code, bank_name and branch_code etc... in Rails

In my rails application, I have bank_details table with columns - account_number, ifsc_code, bank_name and branch_code(Only for India). But I don't know how to validates this columns before save it to database.Plese help me in this.
I will appreciate your help.
Thanks in advance.
In your model, you need to add a validates: your_column.
For example if you want to make sure that account number is present before you save to the database, you need to add validates: account_number, presence: true
There are both pre-built helpers, so you can validate by presence, name, etc, but you can also use a custom method to validate those.
Check out RailsGuides for all the details
There are so many validation that you can apply on your columns, here is a list of possible validation. you can pick as your requirement.
Validation for data should be present
validates :account_number, :ifsc_code, :branch_code, :bank_name, presence: true
data should be positive numbers only
validates :account_number, :branch_code, :numericality => { :greater_than_or_equal_to => 0 }
set length of record
validates :ifsc_code, length: { is: 11 }
validates that the attribute's value is unique right before the object gets saved
validates :account_number, uniqueness: true
In your model you can have something like this:
validates: branch_code
which is a standard validation, making sure its present
Or you can do more validation using regex
validates :bank_name, format: { with: /\A[a-zA-Z]+\z/,
message: "only allows letters" }
Here are some examples of validation:
validates :bank_name, length: { minimum: 2 }
validates :bank_name, length: { maximum: 500 }
validates :bank_name, length: { in: 6..20 }
validates :bank_name, length: { is: 6 }
Or use some advance techniques like so:
validates :bank_name, presence: true, if: "branch_code.nil?"
TransferWise provides an API you can use to validate IFSC codes and Indian account numbers:
IFSC code
https://api.transferwise.com/v1/validators/ifsc-code?ifscCode=YESB0236041
Account number
https://api.transferwise.com/v1/validators/indian-account-number?accountNumber=678911234567891
Documentation here.

Resources