[Dbix-class] Deferred validation via accessors
Paul Makepeace
paulm at paulm.com
Fri Jul 30 20:31:53 GMT 2010
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).
One option seemed to me to have a pre-update() check rather than
having it in the accessor.
What do folks to here?
Paul, who skimmed ::Cookbook & ::ResultSource but didn't see anything jump out
PS Here's some code to see if I'm at least on the right track as far as it goes,
__PACKAGE__->add_columns(
bar_enabled => { accessor => '_bar_enabled' },
foo_enabled => { accessor => '_foo_enabled' },
default_view => { accessor => '_default_view' },
);
sub default_view {
my ($self, $value) = @_;
if (defined $value) {
unless ($value ~~ ['foo', 'bar']) {
die "default_view must be one of 'foo', 'bar'";
}
foreach my $view qw(foo bar) {
if ($value eq $view && !$self->"${view}_enabled") {
die "${view}_enabled must be set before default_view can be $view";
}
}
$self->_default_view($value);
}
return $self->_default_view;
}
sub bar_enabled {
my ($self, $value) = @_;
if (defined $value) {
if (!$value) { # switching if off
if (!$self->_foo_enabled) {
die "bar_enabled cannot be 0 if foo_enabled is 0";
}
unless ($self->_default_view ne 'bar') {
die "bar_enabled cannot be 0 if default_view is bar";
}
}
$self->_bar_enabled($value);
}
return $self->_bar_enabled;
}
sub foo_enabled {
my ($self, $value) = @_;
if (defined $value) {
if (!$value) { # switching if off
if (!$self->_bar_enabled) {
die "foo_enabled cannot be 0 if bar_enabled is 0";
}
if ($self->_default_view eq 'foo') {
die "foo_enabled cannot be 0 if default_view is foo";
}
}
$self->_foo_enabled($value);
}
return $self->_foo_enabled;
}
(If there's a cute way of avoiding that copy&paste I'm all ears, it's
been a long night :))
More information about the DBIx-Class
mailing list