[Dbix-class] Deferred validation via accessors

Ian dbix-class at iandocherty.com
Sat Jul 31 13:04:41 GMT 2010


Paul.

On 30/07/2010 21:31, Paul Makepeace wrote:
> I'm hoping to use custom accessors to do some validation of incoming
> data with reference to existing column data.
>
> I have three fields: foo_enabled, bar_enabled, and default_view.
> Constraint 1: one of foo_enabled or bar_enabled must be on/1 (i.e.
> neither off/0)
> Constraint 2: default_view can take either of 'foo' or 'bar' (not null etc)
> Constraint 3: default_view can only take its value if the
> corresponding {foo,bar}_enabled is set
>
> There's a deadlock here if you can't defer checking. Say we have
> foo_enabled=1, bar_enabled=0, default_view=foo then flip to
> foo_enabled=0, bar_enabled=1, default_view=bar we'd have to order our
> accessor calls to have both 1 (which is annoying).
>
The bottom line is that this is business logic and so does not live in 
the controller. (I assume from your example that it is an MVC Controller)

You are trying to apply the logic by restricting how the database 
accessors are updated. It is difficult to say from your description if 
it belongs in the database abstraction layer either (it could be argued 
either way).

Much simpler and clearer to put an abstraction layer between the 
controller and model which is responsible for taking a number of values, 
checking the relative integrity of the values, then updating the 
database. This abstraction layer may simply be methods in the DBIx 
resultset or the result modules or can in more complicated examples be a 
complete new module.

I would argue that having *any* dbix create/update/delete/find etc. 
methods in a controller is bad practice.

e.g.

# Call business logic which dies if anything is wrong.
eval {
   my_business_logic_method({
     foo          = ..params('foo_enabled'),
     bar          = ..params('bar_enabled'),
     default_view = ..params('default_view'),
   });
};
if ($@) {
   print STDERR "my business logic has failed reason code $@\n";
}

I would argue that this is *much* clearer and although you may not agree
since it is a little more verbose than your example, terseness is not 
always a virtue.

Regards
Ian

<snip>



More information about the DBIx-Class mailing list