Reputation: 13012
This is a two part question.
Part one if my Model that i am writing the validations for is inhering from ActiveRecord::Base
do i need to include ActiveModel::Validations
within that class?? the API for rails doesnt say but here in yehudakatz blog seems to hint that?
part two is where would be the best place to put these validator files? under helpers or as a new model or in lib?
my current validator looks like this
class GenderValidator < ActiveModel::validator
def validate(record)
cred = /(\d{6})(\d{4})(\d{1})(\d{2})/.match(record.id_number.to_s) #breaks up the id into the relevent sections namely birthdate, gender, nationality, validator.
unless cred[0][/\d{13}/] #checks to see if the id is a valid length of numbers if it isnt then skip the validation of gender
return true
else
birthdate = cred[1] #returns a 6 digit string 'yymmdd'
parsed_gender = cred[2] #returns a 4 digit string '0001-4999:female 5000-9999:male'
nationality = cred[3] # should return either a 1 or a 0 1 if the person is foreign or 0 if the person is southafrican
validate_gender(parsed_gender, record)
end
end
private
def validate_gender(parsed_gender, record)
calculate_gender = (parsed_gender <= 4999 ? :female : :male)
unless employee.gender == calculate_gender
employee.errors[:gender] << "Your id indicates you have entered the wrong gender"
end
end
end
an valid id number of each person is optional, but if they do specify it it should check to see if the gender is correct.
if i keep it in the same model the employees model then i get this error
ActionController::RoutingError (uninitialized constant Employee::GenderValidator):
app/models/employee.rb:25:in `<class:Employee>'
app/models/employee.rb:1:in `<top (required)>'
lib/role_requirement_system.rb:19:in `inherited'
app/controllers/employees_controller.rb:1:in `<top (required)>'
librato-rails (0.8.1) lib/librato/rack/middleware.rb:12:in `call'
so i take it they cant be in the same file. what is the best practice for validations? i watched all the rails casts and i have read a few blogs and i am quite new still.
EDIT
in my model i include this class like
include ActiveModel::Validations
and my validations look like this
validates_presence_of :name, :position, :gender
validate :instance_validations, :on => :create
def instance_validations
validates_with GenderValidator
end
just incase you wanted to see that too thanks ahead!
Upvotes: 3
Views: 1603
Reputation: 1612
You do not need include ActiveModel::Validations
My preference to to keep the validation objects in the model folder.
So for model Gender you have a file gender.rb
For the validator GenderValidator you have the file gender_validator.rb
So both files site together in the model folder.
Here is a validator for my Newsletter model
class NewsletterValidator < ActiveModel::Validator
def validate(record)
if record.send_test_email
if test_email_address.blank?
record.errors[:test_email_address] << "Test email address is blank"
end
if record.send_email_to_subscribers
record.errors[:send_test_email] << "You cannot send a test and send to subscribers at the same time"
end
end
end
end
In my Newsletter model I simply have
validates_with NewsletterValidator
You have a spelling mistake in your example
You have
class GenderValidator < ActiveModel::validator
It should be
class GenderValidator < ActiveModel::Validator
Note the capital V
Upvotes: 8