Forum: Ruby on Rails DRY principle form validations

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-13 20:14
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?
B07c187ac858535358faa9365b66e657?d=identicon&s=25 John Tsombakos (Guest)
on 2006-03-13 21:44
(Received via mailing list)
You can use validates_format_of and a regular expression

<http://api.rubyonrails.com/classes/ActiveRecord/Va...

jt
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-13 23:04
John Tsombakos wrote:
> You can use validates_format_of and a regular expression
>
> <http://api.rubyonrails.com/classes/ActiveRecord/Va...
>
> 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.
Fea3202718832fe11a0db6bb44a5cc37?d=identicon&s=25 Avdi Grimm (Guest)
on 2006-03-13 23:11
(Received via mailing list)
Seems like s terrific addition to Rails would be validates_ methods
which generate both server-side and client-side validation, where
possible.
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-13 23:34
Avdi Grimm 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)
Eed3ca2591560a2dd91222d9b62f882d?d=identicon&s=25 Ryan Prins (Guest)
on 2006-03-13 23:54
(Received via mailing list)
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
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-14 01:15
Ryan Prins 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.
858392acd1398aa6071fb1d44cc33842?d=identicon&s=25 John Smilanick (Guest)
on 2006-03-14 19:18
(Received via mailing list)
> 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 Smilanick
Computing Staff - Webmaster
Kavli Institute for Theoretical Physics
University of California, Santa Barbara
jsmilani@kitp.ucsb.edu
(805) 893-6307


On Mar 13, 2006, at 4:15 PM, Cody Skidmore wrote:
Fea3202718832fe11a0db6bb44a5cc37?d=identicon&s=25 Avdi Grimm (Guest)
on 2006-03-15 17:59
(Received via mailing list)
On 3/14/06, John Smilanick <jsmilani@kitp.ucsb.edu> 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
3131fcea0a711e5ad89c8d49cc9253b4?d=identicon&s=25 Julian Leviston (Guest)
on 2006-03-16 00:04
(Received via mailing list)
This seems wrong.
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-16 15:45
Avdi Grimm 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?
Fea3202718832fe11a0db6bb44a5cc37?d=identicon&s=25 Avdi Grimm (Guest)
on 2006-03-16 17:50
(Received via mailing list)
On 3/15/06, Julian Leviston <julian@coretech.net.au> 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
5f699f59b58693ce313995caf4330486?d=identicon&s=25 Ben Anderson (Guest)
on 2006-03-16 18:40
(Received via mailing list)
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.
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-16 19:17
Ben Anderson 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?
5f699f59b58693ce313995caf4330486?d=identicon&s=25 Ben Anderson (Guest)
on 2006-03-16 19:29
(Received via mailing list)
> How would we get a project off the ground to implement this type of
> generation?

writing code is usually the first step :-)
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2006-03-16 19:54
(Received via mailing list)
On 3/16/06, Cody Skidmore <hopefulskeptic@mailinator.com> 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.
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-16 19:54
Ben Anderson wrote:
>> How would we get a project off the ground to implement this type of
>> generation?
>
> writing code is usually the first step :-)

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.
Fea3202718832fe11a0db6bb44a5cc37?d=identicon&s=25 Avdi Grimm (Guest)
on 2006-03-16 20:03
(Received via mailing list)
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
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-16 20:03
Wilson Bilkovich wrote:
> On 3/16/06, Cody Skidmore <hopefulskeptic@mailinator.com> 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.
A63764f318f10379c8b51349b757cf4b?d=identicon&s=25 Jay Levitt (Guest)
on 2006-03-16 22:49
(Received via mailing list)
On Thu, 16 Mar 2006 19:17:06 +0100, Cody Skidmore wrote:

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

Typically, for new, highly-desirable Rails functionality like this,
three
to six programmers would go off and create their own, vaguely
incompatible,
orthogonally incomplete implementations - one or two as a generator, a
few
plugins, and at least one engine.  For best effect, they should all be
named similarly.

Jay Levitt
667bc7479ca9f34ee86b780ba23663e8?d=identicon&s=25 Adam.Cooper (Guest)
on 2006-03-16 22:58
(Received via mailing list)
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
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-16 23:07
Adam.Cooper wrote:
> 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

Getting it organized under one project is kind of what I'm hoping for
here.  Get the guys who are interested in actually putting together a
generator or engine or plugin under just one project.  Get them to agree
on a design, and begin implementation.

I know, that's just a little too much to ask, but it works better when
everyone contributes to the same effort.  :o)

Is anyone interested in actually doing this?
Fea3202718832fe11a0db6bb44a5cc37?d=identicon&s=25 Avdi Grimm (Guest)
on 2006-03-16 23:13
(Received via mailing list)
>  Get the guys who are interested in actually putting together a
>  generator or engine or plugin under just one project.

Can I add "patch" to this list?  It seems like the sort of thing that
might be appropriate in the Rails core.

> Is anyone interested in actually doing this?

Sadly, by the time I bone up on Javascript enough to make myself
useful to this effort, I'm afraid it will be long-solved...

~Avdi
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-16 23:42
Avdi Grimm wrote:
>>  Get the guys who are interested in actually putting together a
>>  generator or engine or plugin under just one project.
>
> Can I add "patch" to this list?  It seems like the sort of thing that
> might be appropriate in the Rails core.
>
>> Is anyone interested in actually doing this?
>
> Sadly, by the time I bone up on Javascript enough to make myself
> useful to this effort, I'm afraid it will be long-solved...
>
> ~Avdi

The AJAX in Action book is about an inch thick.  Not exactly a weekend
read!  :o)
4005a47a8f2ceee49670b920593c1d52?d=identicon&s=25 Ben Munat (Guest)
on 2006-03-17 08:02
(Received via mailing list)
Struts is actually using commons-validator from the Apache Jakarta
project... and I hate
to say it, but I don't think it's very dry.

It has an xml configuration file into which you can put your javascript
validations (in
CDATA tags) or it can link to the name of a javascript file in the
package structure
(that's what the built-in validations do). This javascript is included
into the jsp page
by use a Struts tag (not sure how you include the javascript if you're
not using struts).

However, these javascript files are not run on the server side... there
are separate java
classes for that. I've always thought this isn't the best design...
Apache has had the
Rhino javascript engine for years; they could have used that. And now,
Java 6 is going to
introduce script handling (javascript, php, and ruby! I believe). I hope
they get around
to a re-write after that.

Anyway, I agree that having one source for the validation logic would be
ideal.

b
D57f4a4788599a38494865a121f16bbe?d=identicon&s=25 dseverin (Guest)
on 2006-03-17 18:09
Take also look at known attempts: http://dev.rubyonrails/ticket/861 and
http://www.schuerig.de/michael/boilerplate/

Ben Munat wrote:

> Anyway, I agree that having one source for the validation logic would be
> ideal.
>
>

Well, SQL allows to define fairly good amount of constraints over table
attribute values - I think it's a good place for single source of
validation logic.

Here's list of possible SQL constraint and some thoughts about
complexity of Ruby(or JS) code to perform validations before sending
data  to server:

  1. NOT NULL  - trivial

  2. STANDARD TYPE (numeric, string, boolean, date, time, etc.) -
validation as check if presentation format allows value to be correctly
type-casted can be quite easily performed.

  3. VALUE LIMITS (sizes of varchar, numeric) - trivial

  4. CHECK CONSTRAINTS - are the most complex, as  can include calls to
standard   functions (length(), current_date, trim, etc.), operators(+,
-, /, * etc.),  comparisons( <, >, ==, !=, between etc.), set inclusion
(in, not in),  regular expression matches (=~, !~),  logical operations
(OR, AND, NOT), nested expressions, and refer to SEVERAL columns at once
(say, 'CHECK ( gross_price >= net_price )' ) - and that's only brief
overview :)))

Ideal solution would be to declare ALL constraints in SQL DDL and when
retrieving model metadata a code generator would inject appropriate
methods to model class, thus deriving validations directly from
constraints and produce JS code for client-side validations.
C402e1150580c153c1368573f70e7e82?d=identicon&s=25 Cody Skidmore (cskidmore)
on 2006-03-17 18:26
This is bit off topic, but...

I'm not that crazy about pushing almost any kind of logic onto the data
store.  IMO, rules should be delegated to the middle tier.  Any logic
you put into the data store has to be replicated if you switch to a
different database engine.

At a previous job, we supported three or more database engines at a time
on the same middle tier.  As long as we kept rules in the middle tier,
supporting a different database engine was almost trivial.

Our earlier architecture contained stored procedure, constraints,
triggers, etc, and we were completely bound to one db vender as a
result.
This topic is locked and can not be replied to.