Right off you can be sure that you will never need $c. The
Catalyst context is, well, SHOULD be, entirely irrelevant to all DB
operations. If not, you may have a “broken design.”
The DB has its own proper routes to information
and self-reference. It’s only being consumed by Catalyst, it is not
intrinsically a part of it at all. Generally, no DBIC question is
ever a Catalyst question and vice versa.
So, there are probably a few ways to do what you want, if I’m
correctly guessing what you want; which is to create a club
record, presumably from MyApp::Controller::Club->something with
valid venue.
my $club = $c->model("DB::Clubs")
->create({ some_data => "asdfasdf",
venue => $id });
If your data is InnoDB or equivalent with proper foreign keys this will throw an exception
on a bad venue because your DB will not allow bad integrity to
be stored. Then you just eval and recover in the controller, or
do a general purpose version of same in you /end controller
where $c->errors (all fatals) are available to be handled (and
cleared) or passed along as a server error.
I take it you are trying to avoid things like the following. But
there is nothing wrong with this approach so don’t avoid it out of
some sense of purity. Maybe you don’t know about it. This one will
also throw an error if the venue is bad whether or not your DB cares.
my $venue = $c->model("DB::Venue")->find($id);
$venue->add_to_clubs({ some_club_data => "Without venue" });
Now, the last possibility (well, the last obvious one) is that you
have no DB integrity (your foreign keys are advisory, not enforced)
and you don’t want to do any handling in Catalyst. In this case you
might have to do something like this–
# Inside MySchema::Result::Club.
sub insert {
my $self = shift;
return $self if $self->in_storage;
croak "No venue provided..." unless $self->venue;
my $schema = $self->result_source->schema;
croak "Venue is invalid..."
unless $schema->resultset("Venue")->find($self->venue);
$self->next::method();
}
sub update {
my $self = shift;
my %to_update = $self->get_dirty_columns
|| return $self->next::method(@_);
$to_update{venue} || return $self->next::method(@_);
croak "Venue is invalid..."
unless $schema->resultset("Venue")->find($to_update{venue});
$self->next::method(@_);
}
That’s rough but probably functional (none of this code was tested
but I have used all of the approaches at some point). You can see why
letting the DB handle integrity is saner policy. When you have to code
around it, many edge cases pop up and get messy and can trash performance.
|