Ruby on Rails is radically changing the way developers look at Web
applications, and it’s great to see all the excitement that surrounds the many
innovative features it offers. One of these features is in-model
validation, which is understandably seen as an improvement over validation tied
to the presentation framework.
In
this entry, Todd Huss shows a convincing example of this approach:
class Entry < ActiveRecord::Base
# Relationships
belongs_to :bliki# Validation
validates_length_of :name, :within => 6..100
validates_uniqueness_of :name
validates_format_of :name, :with => /^\w+$/,
:message => "cannot contain whitespace"
validates_length_of :content, :minimum => 10
validates_associated :bliki
end
This kind of code is fairly usual to any regular Ruby on Rails developer to
the point where it’s actually easy to overlook that there is something very
wrong with it: there is no easy way to capture this validation logic for
reuse elsewhere.
I could move this validation to a common class but it’s not good enough, for
two reasons:
I still might want to fine tune a few parameters here and there (sometimes,
the length of the name can be 6..100, other times 5..10 but the other
constraints need to stay in place).
Not all my ActiveRecord objects extend the same class.
Has anyone tried to use a mix-in to achieve this? Any other idea?
#1 by Zsolt on December 6, 2005 - 12:18 pm
Quote
One gripe I have with ActiveRecord is that the validation normally kicks in only when the entity is persisted or updated. This means your — possibly invalid — domain object goes through the web layer and your business logic until it gets caught by the validation framework.
I prefer the XWork/WebWork approach where the validation mechanisms can be context sensitive, and always apply immediately when the input data reaches the controller.
#2 by David Heinemeier Hansson on December 6, 2005 - 12:52 pm
Quote
Cedric: It’s actually quite easy to bundle all this up in either a mixin or your own meta validation. You could wrap it up into something like validates_cedricness_of :name and have that include both length, uniqueness, and format.
Zsolt: You can just call model.valid? to do this.
#3 by Simon Harris on December 6, 2005 - 1:02 pm
Quote
Zsolt,
You can manually invoke validation whenever you like by calling valid?
#4 by Zsolt on December 6, 2005 - 1:09 pm
Quote
Cool
#5 by Cedric on December 6, 2005 - 1:10 pm
Quote
Great, thanks David!
#6 by Bill Kress on December 6, 2005 - 5:37 pm
Quote
For a system with a lot of GUIs, you really need to have a generic mechanism to transfer data back and forth anyway.
You really should define that mechanism with meta data. At least an XML template listing the objects/attributes rather than just throw a hashtable out there.
With those requirements identified, adding a simple drop-in validation into the XML definition should be pretty easy.
Just specify the name of the class used to validate the field and an optional string parameter. It certainly makes more sense than specifying the validation relationship in code anywhere.
This would allow you to specify much more than validations too, you could identify what to do with the data when it connects with any other sub-system.
Oh well, that’s how I was designing it anyway.
#7 by Anonymous on December 6, 2005 - 5:42 pm
Quote
XML SUCKS!
Keep your horrid metadata away from rails!
Mixins can keep rails models much nicer, and keep the application simple.
#8 by Todd Huss on December 6, 2005 - 6:10 pm
Quote
There’s nothing wrong with the code if you don’t want to reuse it though
Thanks for the reference to my blog, nice to see folks are reading it. If I reach a point where I need to validate a name the same way in other parts of the code that would violate the DRY principle I like DHH’s suggestion.
#9 by Jason Carreira on December 7, 2005 - 11:42 am
Quote
Well, you don’t just call valid() on an object to validate it, no, you ask the validation framework to validate the object:
ActionValidatorManager.validate(object, context);
But, as you do in Ruby, we could add this as a mixin using AOP to any objects we like to have the validation framework validate them.
One question for the Rails folks… How do you do context-sensitive validations? Also, how do you collect the validation error messages, and how do you localize them? These are all requirements that my validation framework (the XWork Validation Framework) had to address for real-world requirements at work.
#10 by Michael Neale on December 8, 2005 - 2:58 pm
Quote
I really like the Mixin idea. You can then break out all your common validation rules into a set of declarative classes, and mixin as needed. Kind of like meta-data validation rules, but its not metadata. Nice.
Three cheers for mixins.
#11 by Jesus on December 8, 2005 - 3:31 pm
Quote
What you need to do is Mixin with AOP then Inject with IoC, squeeze in a Context, implement IValidatable and finally let it sit overnite.
wallah !!!
#12 by David Heinemeier Hansson on December 9, 2005 - 12:22 pm
Quote
We have not had a need to do context-sensitive validations and I’d argue that most applications do not. So the the validation rules that you specify in the Rails models are the absolutes, the “must always be true” kind of validations.
If you have context-sensitive validations needed on top of that, you’ll have to roll on your own. So this is one of those “most people, most of the time” things. We’re not after the “all people, all of the time” kind of framework coverage.
#13 by Alex Shneyderman on December 19, 2005 - 11:48 am
Quote
[quote]
We have not had a need to do context-sensitive validations and I’d argue that most applications do not. So the the validation rules that you specify in the Rails models are the absolutes, the “must always be true” kind of validations.
If you have context-sensitive validations needed on top of that, you’ll have to roll on your own. So this is one of those “most people, most of the time” things. We’re not after the “all people, all of the time” kind of framework coverage.
[/quote]
hmm, well look at the first post in this thread. There is a real use case for the need of it. What I like in XWork/WW approach (same goes for Spring with its rules validations) even more is that I can run the same validation in multiple layers presentation and business, and if my business and presentation sit on the same JVM I can propagate validation that was done already into the business layer so it does not waste its time re-checking. He, he no need for context sensitive validation –> you must be kidding me.
#14 by Alex Shneyderman on December 19, 2005 - 11:49 am
Quote
[quote]
We have not had a need to do context-sensitive validations and I’d argue that most applications do not. So the the validation rules that you specify in the Rails models are the absolutes, the “must always be true” kind of validations.
If you have context-sensitive validations needed on top of that, you’ll have to roll on your own. So this is one of those “most people, most of the time” things. We’re not after the “all people, all of the time” kind of framework coverage.
[/quote]
hmm, well look at the first post in this thread. There is a real use case for the need of it. What I like in XWork/WW approach (same goes for Spring with its rules validations) even more is that I can run the same validation in multiple layers presentation and business, and if my business and presentation sit on the same JVM I can propagate validation that was done already into the business layer so it does not waste its time re-checking. He, he no need for context sensitive validation –> you must be kidding me.
#15 by S. Potter on April 23, 2006 - 3:21 pm
Quote
Ref: Contextual validation use cases
I think this is mis-named to be honest (and getting lots of google hits for the wrong thing). I would call this multi-layer validation and the great thing about RoR is the fact that it isn’t clunky like Spring and other Java frameworks I have worked with (I have had 8-9 years of professional Java experience and 2 year of Python and Ruby, so I am not just a Ruby head or anti-Java head).
In fact, even Marc Fluery of JBoss (a big Java head) agrees that keeping your apps as thin and stateless as possible is best for scaling apps to handle significant load. You may or may not like his arrogant way, but I think in this instance he makes a genuinely great point. Why uber-architects insist on having multiple seperate containers for their apps unless extremely domain-specific use cases mandate this is beyond me.
I have worked with plenty of uber-architects that want to redesign the world to make it even more generic than the vast majority of real world use cases need them to be and ALL of those projects have been complete failures. Of course, the opposite extreme also produces project failures. However, if we agree that RoR’s main focus is on helping application developers build streamlined web applications and that Marc Fluery has a good point, then I would argue that this is a moot point.
But if you like Spring so much, stick to it, please!
As for those that are interested in doing what I would call context-sensitive validation…
RoR provides the validate, validate_on_create and validate_on_update protected methods for application developers to override them. This seems like the perfect place to do contextual validation.
#16 by vipul on July 26, 2006 - 7:21 am
Quote
how to perform email validation i m confused when i m using following coe it return code it not consider index(”) method of ruby in model.
mymodwl.rb
def validate
apos=:email.index(‘@’).to_i
dotpos=:email.rindex(“.”)
lastpos=:email.length-1;
if (apos 3 || lastpos-dotpos<2)
errors.add(:email, “is missing or invalid”)
end
end
#17 by lurker on December 25, 2006 - 12:29 am
Quote
apos=:email.index(/@/).to_i
use this code
#18 by Aditya Agustyana on February 13, 2007 - 9:23 pm
Quote
i have make upload image form, i save path info about image on database and i placed uploaded image to public/images/user_pix/ directory
everything is running well, except i can’t validate content type of image, my apps accept jpg,gif & png filetype only
so guys, would you please tell me how to validate content type when you save/update image data
*i’m sorry if my english bad
#19 by Anonymous on March 9, 2007 - 4:20 am
Quote
hkh
#20 by bijah on November 25, 2007 - 3:26 pm
Quote
In my address model, I have address line 1 and address line 2. Address line 2 is optional and I want to validate it when present. So, I defined the following validate function.
def validate
if(!address_line_2.nil? and !address_line_2.blank?)
validates_length_of :address_line_2, :maximum => 30, :too_long => ” exceeds %d characters”
validates_format_of :address_line_2, :with => /^(\w+|(\s|,|-|\.|’)*)+$/
return true
end
end
But rails throws a NoMethodFound exception for validates_length_of. How can I fix it?
#21 by bijah on November 25, 2007 - 7:53 pm
Quote
OK. I solved it as follows:
validates_length_of :address_line_2, :maximum => 30, :too_long => ” exceeds %d characters”, :if => Proc.new { |a| !a.addres
s_line_2.blank? }
validates_format_of :address_line_2, :with => /^(\w+|(\s|,|-|\.|’)*)+$/, :if => Proc.new { |a| !a.address_line_2.blank? }
But I still would like to know the cause for the NoMethodFound error in the previous approach.
Thanks.
#22 by sdf on April 23, 2008 - 6:21 am
Quote
ds
#23 by Gevorik u Goqor on April 23, 2008 - 6:22 am
Quote
Lav ban eq asum
#24 by aditi on May 22, 2008 - 10:21 pm
Quote
hello
#25 by Anonymous on October 14, 2008 - 11:48 am
Quote
ruby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input ruruby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input ruby rails input validation example codevalidatiruby rails input validation example codeon exampruby rails input validation example codele coderruby rails input validation example codeuby railruby rails input validation example codes input ruby rails input validation example codevalidatiruby rails input validation example codeon exampruby rails input validation example codele codebruby ruby rails input validation example coderuby rails input validation example coderuby rails ruby rails input validation example codeinput validation example coderuby rails input validation example coderuby rails input validation example coderails input validation example codey rails ruby rails input validation example codeinput ruby rails input validation example codevalidation example codevalidation example coderuby raruby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example codeils input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example coderuby rails input validation example code