Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Catalyst / DBIx::Class - accessing a different table from the model

by Your Mother (Archbishop)
on Feb 16, 2015 at 19:50 UTC ( [id://1116921]=note: print w/replies, xml ) Need Help??


in reply to Catalyst / DBIx::Class - accessing a different table from the model

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.

Replies are listed 'Best First'.
Re^2: Catalyst / DBIx::Class - accessing a different table from the model
by stonecolddevin (Parson) on Feb 17, 2015 at 17:15 UTC

    The only nitpick I have is with "eval and recover". Try::Tiny cleans this up quite nicely, or use Throwable to create actual exceptions and keep things less crappy.

    Three thousand years of beautiful tradition, from Moses to Sandy Koufax, you're god damn right I'm living in the fucking past

      Well, that was back-of-the-napkining. :P I use Try::Tiny sometimes and I rely on /end handling myself; also newer Perls (5.16+ IIRC) do eval+$@ better so it’s not as important a caveat now and frankly I was never bitten by it in the past. I agree that exception objects can be a good idea, I posted a sample on that not long ago, but it’s not something that lends itself to inclusion in snippets.

      (Update: 5.14 is where better eval and $@ came in. Not 5.16 as previously suggested.)

Re^2: Catalyst / DBIx::Class - accessing a different table from the model
by mkchris (Sexton) on Feb 17, 2015 at 10:17 UTC
    Thank you for that - I think I prefer the second option actually (all tables are InnoDB with enforced foreign keys) - I think I will try that or a variation on it, I never thought of that. Thanks again.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1116921]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-23 23:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found