DRY principle form validations


#1

We are wondering how you’d validate a credit card number or a SSN
without writing Javascript and Ruby code.

Would it be through Rails’ AJAX support?


#2

You can use validates_format_of and a regular expression

http://api.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html#M000686

jt


#3

Seems like s terrific addition to Rails would be validates_ methods
which generate both server-side and client-side validation, where
possible.


#4

Avdi G. wrote:

Seems like s terrific addition to Rails would be validates_ methods
which generate both server-side and client-side validation, where
possible.

Think of the drool that would cause. :o)


#5

You wouldn’t need AJAX at all, actually, IMO. But, I’m kind of confused
since you say you don’t want JavaScript, but the J in AJAX stands for
JavaScript. shrug

What I’d suggest if you want instant feedback on the form is to use the
onBlur attriblte on the input field to exectute some validation
javascript
in addition to the back end check that you do. You should have both to
account for users who have JS disabled, or get around it some how. For
stuff
that is sensitive like this, I’d prefer a code level check and throw
them
back to the form as opposed to an instant check. But, if you are only
checking the formatting, like a SSN is xxx-xx-xxxx or that a credit card
number is yyyyyyyyyyyyyyyy then you might be ok with java script.

Ryan


#6

Ryan P. wrote:

You wouldn’t need AJAX at all, actually, IMO. But, I’m kind of confused
since you say you don’t want JavaScript, but the J in AJAX stands for
JavaScript. shrug

What I’d suggest if you want instant feedback on the form is to use the
onBlur attriblte on the input field to exectute some validation
javascript
in addition to the back end check that you do. You should have both to
account for users who have JS disabled, or get around it some how. For
stuff
that is sensitive like this, I’d prefer a code level check and throw
them
back to the form as opposed to an instant check. But, if you are only
checking the formatting, like a SSN is xxx-xx-xxxx or that a credit card
number is yyyyyyyyyyyyyyyy then you might be ok with java script.

Ryan

Thank for the feedback Ryan. Yeah, I’m aware of what the acronym stands
for. I [thought] the Rails framework had built in AJAX support to
eliminate most of the need for writing Javascript. It in fact, makes
AJAX ridiculously simple. :o)

What we want to avoid is writing server-side code to validate fields,
and then adding our own Javascript a second time to validate the data on
the client. One of the key points to all this is “Don’t Repeat
Yourself”. If the only way to do it is to write the validation code
twice, you’re violating the DRY principle right?

Personally, I prefer validating on the server-side also. My application
will be a large business application, and I [should] be able to require
customers to have broadband. Internet latency could still be a problem,
but returning validation errors shouldn’t take more than a second, so I
don’t really see the problem.

In any case, if there is a technique to improve response even further, I
need to find it.


#7

What we want to avoid is writing server-side code to validate fields,
and then adding our own Javascript a second time to validate the
data on
the client. One of the key points to all this is “Don’t Repeat
Yourself”. If the only way to do it is to write the validation code
twice, you’re violating the DRY principle right?
This is the unfortunate case when you can’t help repeating yourself.
If the server is not validating the data as it comes in then someone
could conceivably reproduce the post action of your form and force
invalid data into any field. Javascript is the only way to get
instant feedback, but if you are relying solely on javascript for
validation then you can be assured someone can weasel around it.

You could try playing with observe_field and see if you can have it
call your validation on that field, but you will likely have to
redraw much of the page to have consistent validation messages and I
can imagine any lag in this process will cause data loss. Not to
mention this could be much more difficult than adding a little
javascript validation.

-John


John S.
Computing Staff - Webmaster
Kavli Institute for Theoretical Physics
University of California, Santa Barbara
removed_email_address@domain.invalid
(805) 893-6307

On Mar 13, 2006, at 4:15 PM, Cody S. wrote:


#8

On 3/14/06, John S. removed_email_address@domain.invalid wrote:

This is the unfortunate case when you can’t help repeating yourself. If the
server is not validating the data as it comes in then someone could
conceivably reproduce the post action of your form and force invalid data
into any field. Javascript is the only way to get instant feedback, but if
you are relying solely on javascript for validation then you can be assured
someone can weasel around it.

You’re missing the point of DRY. It’s not that actions are never
duplicated, but that we only write it once, in one place. If a
validates_* method could be used to generate both server-side and
client-side (JavaScript) validation, then it would be a very DRY
solution. The validation might be repeated, but we only write the
validation requirement once.

~Avdi


#9

This seems wrong.


#10

John T. wrote:

You can use validates_format_of and a regular expression

http://api.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html#M000686

jt

Thank you for the reply.

This looks like it happens on post for the page. It would be great to
improve the user experience by notifying them when something on the page
is invalid as quickly as possible (that being without posting the entire
page). It looks like the only way to do that is through AJAX.

Maybe this just isn’t much of a big deal as bandwidth becomes less of an
issue for users. Someone has proposed to me that making a user wait for
a couple of seconds to find out a credit card number is invalid reduces
the user experience, and wants to know if there is a better way to
validate the card number other than posting the entire page.

It seems like the only way to do so is through RoR’s AJAX support.

It might be possible to use the events on the input tag to look up the
credit card information a.s.a.p when enough information is entered.


#11

On 3/15/06, Julian L. removed_email_address@domain.invalid wrote:

This seems wrong.

In “The Pragmatic Programmer”, which introduced the “DRY”
principle, the principle is defined thus:

Every piece of knowledge must have a single, unambiguous,
authoritative
representation within a system.

Dave & Andy go on to elaborate:

At the coding level, we often need to have the same information
represented
in different forms. Maybe we’re writing a client-server application,
using
different languages on the client and server, and need to represent
some
shared structure on both. […] Often the answer is to write a
simple filter or
code generator. Structures in multiple languages can be built from a
common metadata representation using a simple generator[…] The
trick is
to make the process active: this cannot be a one-time conversion, or
we’re
back in the position of duplicating data.

In this case, the validates_* declaration is the generator, which
would take an abstract validation specification and translate it into
both server-side (Ruby) and client-side (JavaScript) representations.

~Avdi


#12

Avdi G. wrote:

You’re missing the point of DRY. It’s not that actions are never
duplicated, but that we only write it once, in one place. If a
validates_* method could be used to generate both server-side and
client-side (JavaScript) validation, then it would be a very DRY
solution. The validation might be repeated, but we only write the
validation requirement once.

~Avdi

I’m with Avdi all the way here. But, if there isn’t a way to do that,
I’ve got the AJAX in Action book and will bone up on how to make it
happen the hard way.

It would be better to have the API support this type of validation
though.

Hey, maybe after I grow up and become a real Rails developer this will
become my pet project. :o) I’d do it now, but you’d see some really
fugly code. lol

This seems wrong.

Julian, what do you mean? What seems wrong?


#13

Ben A. wrote:

If someone does look into implementing this (it would be a very nice
addition), you may want to check out how struts does it. They were
doing this over 2 years ago. i.e. generating the server side and
client side code from the same config file.

This would be a magnet attracting more web developers, don’t you think?

How would we get a project off the ground to implement this type of
generation?


#14

How would we get a project off the ground to implement this type of
generation?

writing code is usually the first step :slight_smile:


#15

On 3/16/06, Cody S. removed_email_address@domain.invalid wrote:

My initial reaction is to have the form helpers (select, text_field,
etc.) interrogate the models that they are generating inputs for, and
invoke a Javascript helper library to dynamically build JS
validations.
Getting from that sentence to a crude piece of working code actually
doesn’t sound too difficult. Maybe I should give it a try today.


#16

If someone does look into implementing this (it would be a very nice
addition), you may want to check out how struts does it. They were
doing this over 2 years ago. i.e. generating the server side and
client side code from the same config file.


#17

Ben A. wrote:

How would we get a project off the ground to implement this type of
generation?

writing code is usually the first step :slight_smile:

Okay Mister Obvious…err, maybe its me that’s Mister Obvious. :o) This
is something I’d need, and if I have to write JS anyway, I’ll have to
figure out how to setup the project and start running, but I’m trying to
run before I can walk here.

After I get a clue, I’ll put in some work if anyone wants to join me.
It is a generator we could definitely use as a community.

Add one more to the pile of to-do’s.


#18

I took a quick look at the Rails code (1.0), and it looks like this
approach would work, IF you also patched the validates_* methods so
that they add an annotation to the model about what needs to be
validated. It looks like currently they just add a filter.

~Avdi


#19

Wilson B. wrote:

On 3/16/06, Cody S. removed_email_address@domain.invalid wrote:

My initial reaction is to have the form helpers (select, text_field,
etc.) interrogate the models that they are generating inputs for, and
invoke a Javascript helper library to dynamically build JS
validations.
Getting from that sentence to a crude piece of working code actually
doesn’t sound too difficult. Maybe I should give it a try today.

I won’t know what you are talking about until I finish reading the Rails
book.


#20

That sounds about right for my impression of the rails community.

Instead of a DRY principle we really should have something like a DRYOO
where its Don’t Repeat Yourself Or Others principle. (or some other
cuter
variation.)

I would really like to see this feature and I could see a lot of people
using it but lets hope its done right instead of the 10 login generators
which 90% are out of date and dead.

Adam