Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^2: Maybe database tables aren't such great "objects," after all ...

by sundialsvc4 (Abbot)
on Mar 25, 2011 at 18:05 UTC ( [id://895556]=note: print w/replies, xml ) Need Help??


in reply to Re: Maybe database tables aren't such great "objects," after all ...
in thread Maybe database tables aren't such great "objects," after all ...

I would enjoy finding references in the literature about what you mean by “Fat models.”   And, by extension, how you may “achieve them” within the DBIC (and DBICx) frameworks.   (These technologies are changing and evolving so fast...)

Replies are listed 'Best First'.
Re^3: Maybe database tables aren't such great "objects," after all ...
by Your Mother (Archbishop) on Mar 26, 2011 at 05:16 UTC

    Heh. I don’t actually know if "fat model" is a term outside the Perl lists/sites I frequent. I don’t have links right now but if some turn up, I’ll /msg you and update. I do have some demo/discussion for consideration.

    The idea is simple: business logic is consumed by everything that consumes the model (DB code) so it needs to be in the same place to avoid duplication. It’s an extension of the MVC debate which makes the Controllers *very* thin, doing as little as possible and containing no business logic outside of authorization style stuff, the View being quite dumb and not doing much either, and the Model being "fat."

    In a web app, the Controllers and Views might end up doing things with data; simplistic example: summing. In the fat Model this would be in the schema code.

    This example, being simplistic, will only involve information that is available to the DB/schema already. It could involve external info/models/services. This is where things can get really "fat" if needed. You’d want the external stuff abstracted well so that you could mock it or run safe dev versions easily.

    Example - checkout_total for a cart full of items

    Cart has items, items have a cart, and items have a cost.

    Obviously the information to get a sum of the items in the cart is available and can be put together a couple different ways. But it’s a multi-step process that is going to be needed over and over, so rather than putting it into DBIC syntax (which can be hairy or alterantively verbose for this kind of thing), or raw SQL, or letting an iterator do sums in a view, or some combination of all of those depending on the context, we’ll put it in the model.

    Since it’s an ORM, we already know what calling it should look like: $cart->checkout_total. There is no limit to how many of this kind of helper we can write and what it can do is only limited by judgement.

    Let your mind race ahead to write out checkout_total. What does it look like? Here’s the idiomatic implementation with DBIC–

    sub checkout_total { +shift->items->get_column("cost")->sum; }

    Already, I hope, you can see that once you get your chops down, DBIC makes some easy but verbose things even easier and brief. Spelled out–

    # Inside My::Schema::Cart or an auxillary class only # loaded into the space on demand. sub checkout_total { # My::Schema::Cart object. my $self = shift; # items is a has_many relationship. my $items_rs = $self->items; # ->items_rs to avoid contex ambiguity +. # Get a DBIx::Class::ResultSetColumn object for cost. my $cost_col = $items_rs->get_column("cost"); # Perform SUM. my $sum = $cost_col->sum; return $sum; }

    After you get your legs, the first version becomes more legible than the second. And this is really a baby example. You can continue this sort of thing, riding the relationships, to achieve really powerful queries that remain readable as they become more complex. The business logic can become self-documenting and every piece of every query can be individually testable which will not be the case with SQL libraries or hand written DBI stuff.

    And now the full, working, demo code–

    That example is fun and actually useful but a little weak because it’s based on a Result. Resultset stuff is where it gets really cool. There is a really good walk-through of that here: dbix-masterclass.xul, though no one seems to support XUL at this time so you might just have to read the plain text source of the slides.

    The caveat with DBIC is that it’s not easy. The learning curve is pretty steep. I think it amply repays the investment.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2024-04-23 07:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found