Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

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

by Your Mother (Archbishop)
on Mar 25, 2011 at 17:38 UTC ( [id://895549]=note: print w/replies, xml ) Need Help??


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

Home grown? Well, there's your problem right there.

This is a difficult problem space. Any naïve attempt at it is going to be bad. What moritz said about DBIC is important: it has notions of the abstractions that are actually involved and not just that of the table.row and the DBI connection. It also makes them lazy and highly extensible.

Your point #2 is an important design consideration and why many of us seem to have arrived on the notion of Fat models being the right design. This is quite easy to achieve in DBIC with different base classes, add ins, inflation, etc. Which makes unit testing really easy. E.g., theoretical and untested but close if not already correct–

use My::Schema; my $schema = My::Schema->connection("dbi:SQLite::memory:"); $schema->deploy; $schema->populate( my_baseline_fixtures() ); # Set 'em all up if you have logic not loaded by default. $schema->load_namespaces( default_resultset_class => "+My::BizLogiks" +); # Or customize per class if necessary. for my $source ( $schema->sources ) { print $source, $/; $schema->resultset($source)->result_class("My::BizLogiks::" . $sou +rce); } # Do some tests!!!

Update: fixed a typo; extended comment.

  • Comment on Re: Maybe database tables aren't such great "objects," after all ...
  • Download Code

Replies are listed 'Best First'.
Re^2: Maybe database tables aren't such great "objects," after all ...
by sundialsvc4 (Abbot) on Mar 25, 2011 at 18:05 UTC

    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...)

      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://895549]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2024-09-18 03:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    The PerlMonks site front end has:





    Results (23 votes). Check out past polls.

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.