rails3 doesn't load my validators in lib - ruby-on-rails

I put EmailValidator in lib/validators/email_validator and it's not workings (I put root/lib in the load_path)
here is the code.. I put the class in module validators as the parent folder name
class Validators::EmailValidator < ActiveModel::EachValidator
def validate_each(object, attribute, value)
unless value =~ /^([^#\s]+)#([a-z0-9]+\.)+[a-z]{2,}$/i
object.errors[attribute] << (options[:message] || "is not formatted properly")
end
end
end
I get the error Unknown validator: 'email'

You have two options:
Either put your custom validator under config/initializers.
Or add lib/validators to the autoload path in config/application.rb.
config.autoload_paths << "#{config.root}/lib/validators"
Personally I would go with the second option as lib/validators makes for good encapsulation.

Since you put your custom validator in the Validators:: in the lib/validators, you have to reference it with that namespace also.
validates :email, presence: true, :'validators/email' => true

UPDATE: You need this:
module Validators
class EmailValidator < ActiveModel::EachValidator
def validate(object, attribute, value)
unless value =~ /^([^#\s]+)#([a-z0-9]+\.)+[a-z]{2,}$/i
object.errors[attribute] << (options[:message] || "is not formatted properly")
end
end
end
end
class YourModel < ActiveRecord::Base
include Validators
validates :email, :presence => true, :email => true
end
Otherwise, you need to put your validator class under the ActiveModel::Validations namespace. When you namespace a class, ActiveRecord isn't going to see it, if that namespace isn't a namespace it has already included.

Related

confusion over validates_with custom validations syntax shown in rails guide

I am attempting to use the validates_with custom validations helper with Rails 4.
The following code is working in my application:
class Photo
validates_with CleanValidator
include ActiveModel::Validations
end
class CleanValidator < ActiveModel::Validator
def validate(record)
if record.title.include? "foo"
record.errors[:title] << "Photo failed! restricted word"
end
end
end
However I want to pass this helper to multiple attributes in multiple models, not just :title.
There is an example in validates_with section of guide that contains the following example:
class GoodnessValidator < ActiveModel::Validator
def validate(record)
if options[:fields].any?{|field| record.send(field) == "Evil" }
record.errors[:base] << "This person is evil"
end
end
end
class Person < ApplicationRecord
validates_with GoodnessValidator, fields: [:first_name, :last_name]
end
This is what I want to achieve, substituting [:fields] for [:title] in my code example so that I can use CleanValidator for multiple models and multiple attributes (User.name, Photo.title etc).
I think you want the other example from the guides, each validator. You should be able to do
class CleanValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless ["Evil", "Other", "Restricted", "Words"].include?(value)
record.errors[attribute] << (options[:message] || "is a restricted word")
end
end
end
class Photo
include ActiveModel::Validations
attr_accessor :title
validates :title, clean: true
end

Rails plug and play validations

Here is my example
class User < ActiveRecord::Base
validates_with EmailValidator
end
class EmailValidator < ActiveModel::Validator
def validate(record)
if record != someregex
record.errors.add(:email, 'invalid email')
end
end
end
Now I can use this EmailValidator for any model. But my requirement is to validate its uniqueness and presence also for that particular model.
If I can achieve this I can use this EmailValidator for any model email validation with functionalities unique, presence.
Then I can achieve more reusable Validator.
You can do this by rewriting your validator to be EachValidator:
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if attribute !~ someregex
record.errors.add attribute, (options[:message] || 'invalid email')
end
end
end
Then in your model:
validates :email, email: true, uniqueness: true, presence: true
Hope that helps.

ActiveModel custom EachValidator not found

My EachValidator cannot work on Rails 4.1.5.
My Product model:
class Product < ActiveRecord::Base
has_many :tags
validates :tags, tags_size: {minimum: 1, maximum: 10}
end
My Validator, I put it in app/validators/tags_size_validator.rb
class TagsSizeValidator < ActiveModel::Validator
def validate_each(record, attribute, value)
if value.size < options[:maximum]
record.errors[attribute] << (options[:message] || "must have at most #{options[:maximum]} tags.")
end
if value.size > options[:minimum]
record.errors[attribute] << (options[:message] || "must have at lease #{options[:minimum]} tags.")
end
end
end
end
I have made it autoload in application.rb
config.autoload_paths += %W["#{Rails.root}/app/validators/"]
When I put the validator at the same file as the Product model, it worked perfectly. But in separated file it failed. Are there any steps I have missed? Please advise. Thanks.
Try inheriting from ActiveModel::EachValidator rather than ActiveModel::Validator:
class TagsSizeValidator < ActiveModel::EachValidator
...
Also you shouldn't have to add it to your autoload_paths in Rails 4.1.

Rails 3, Unknown validator: 'EmailValidator'

I try to add an email-validator in my rails app. I created the following file /lib/validators/email_validator.rb
class EmailValidator < ActiveModel::EachValidator
def validate_each(object, attribute, value)
unless value =~ /^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
object.errors[attribute] << (options[:message] || "is not formatted properly")
end
end
end
In the application.rb I added this line:
config.autoload_paths << "#{config.root}/lib/validators"
And here is my User model:
class User < ActiveRecord::Base
attr_accessible :email, :password,:name
validates :email, :presence => true, :uniqueness => true, :email => true
end
If i want to start the server I got an error:
Unknown validator: 'EmailValidator' (ArgumentError)
Has anybody an idea how I can fix this problem?
If you place your custom validators in app/validators they will be
automatically loaded without needing to alter your
config/application.rb file.
Resource: Where should Rails 3 custom validators be stored? (second answer)
This error occures, because rails loads model file before your validation file
Try to require your validation file manually at the start of your model file
require_dependency 'validators/email_validator.rb'
Try the modified User model;
class User < ActiveRecord::Base
attr_accessible :email, :password,:name
validates :email, :presence => true, :uniqueness => true
end

Client side validations undefined method `validates_email'

I copied the code from client_side_validations page. And i had error
undefined method validates_email for #<Class:0x007ff3382428a8>
When i put includes ::Validations in my model this error disappeares but validation doesn't work at all.
app/validators/email_validator.rb
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attr_name, value)
unless value =~ /^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
record.errors.add(attr_name, :email, options.merge(:value => value))
end
end
end
# This allows us to assign the validator in the model
module ActiveModel::Validations::HelperMethods
def validates_email(*attr_names)
validates_with EmailValidator, _merge_attributes(attr_names)
end
end
config/locales/en.yml
# config/locales/en.yml
en:
errors:
messages:
email: "Not an email address"
app/assets/javascripts/rails.validations.customValidators.js
// The validator variable is a JSON Object
// The selector variable is a jQuery Object
window.ClientSideValidations.validators.local['email'] = function(element, options) {
// Your validator code goes in here
if (!/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.test(element.val())) {
// When the value fails to pass validation you need to return the error message.
// It can be derived from validator.message
return options.message;
}
}
models/comment.rb
class Comment < ActiveRecord::Base
attr_accessible :content, :email, :ip, :name, :post_id
belongs_to :post
validates_presence_of :content, :email, :post_id, :name
validates_email :email
end
I don't see you including your module. Also, depending on where you put your module, you will sometimes need to "require" it. And also, try:
include <Module name>
instead of
includes <Module name>
hope this will help

Resources