[Catalyst] Where should constraints go

Carl Franks fireartist at gmail.com
Fri Nov 3 16:15:11 GMT 2006


On 03/11/06, Ian Docherty <ian at iandocherty.com> wrote:
> Carl Franks wrote:
> >
> > I made on very basic start [1] on being able to automatically create
> > constraints from the database column types. At the moment it only
> > supports mysql, and it's also probably very out-of-sync with the
> > current svn trunk - but I'd /really/ like to see it finished, and I
> > /really/ don't have any time to work on it, so if you want to take a
> > look and do something with it, that'd be great.
> > My primary goal was to get it working with HTML::Widget as
> > H-W-Constraint-DBIC [2], but there's no reason it couldn't be
> > integrated with any other validation package.
> >
> > [1]
> > http://dev.catalyst.perl.org/repos/bast/branches/DBIx-Class/columns_info_for
> >
> > [2]
> > http://dev.catalystframework.org/repos/Catalyst/trunk/HTML-Widget-Constraint-DBIC/
> >
> >
> > Carl
> Carl
> Creating the constraints is not really the problem. Your approach
> certainly helps and one that any ORM should include. I can see that it
> would take a fair amount of work to cover all bases.
>
> Putting these sort of constraints is the duty of either the database
> level (where they naturally go anyway) or perhaps in the business logic
> layer.
>
> My problem is finding a clean way of getting these constraints out of
> the Model and into the View so that I can generate meaningful error
> messages without hard-coding them in the templates. By 'clean' I mean
> not having to code the Controller to act as the middle-man and just pass
> them from the Model to the View.

The purpose of the "columns_info_for" branch code is to mark columns
with such flags as
'data_type', 'size', 'length_in_bytes',
or for integers... 'is_unsigned', 'range_min', 'range_max'

Then you just need to tell the validation/form package which DBIC
column corresponds to the CGI parameter, and the validation/form
package should be smart enough to check the input against the flags
set, and set an appropriate error message if it fails.

So if your 'username' column is varchar(16), DBIC would mark it
data_type => 'varchar',
size => 16,
and if the input is longer than that, then the validation package can
set the message "must be no longer than 16 characters".
The HTML::Widget equivalent would be:
$w->constraint( String => 'username' );
$w->constraint( Length => 'username' )->max( 16 )->message( 'must be...' );

If your 'age' column is the mysql column "unsigned tinyint", then DBIC
would mark it
data_type => 'tinyint',
is_unsigned => 1,
range_min => 0,
range_max => 256.
Again, the validation package can set appropriate error messages if
the input doesn't match those specs.
The HTML::Widget equivalent would be:
$w->constraint( Integer => 'username' )->message( 'must be an integer' );
$w->constraint( Range => 'username' )->min( 0 )->max( 256 )->message( '...' );
Which should be entirely possible to automate.

> For example, if a
> constraint was put on a DATE field such that it could not be later than
> NOW and no earlier than NOW - 20 Days. (for example).

I don't get your example.
Is this 'constraint' something that's defined in the database as a
Stored Procedure or Function?
If so, then no, I don't see any way of automatically getting that
specification into the View, unless you use a database that lets you
use native perl-code functions, and you can use the exact same code in
the View, and you use some sort of mechanism to ensure that the
database function stays in sync with the View.

Carl



More information about the Catalyst mailing list