On Wed, Feb 06, 2002 at 10:44:07AM -0500, Perrin Harkins wrote:
> > Hmmm ... my immediate problem with that is that as Class::DBI handles
> > relational database mapping, this could easily end up pulling in the
> > entire database!
> I thought people typically modelled single records with their O/R classes.
> That's what I do. I don't create objects for data I don't need.
Class::DBI isn't really for Object->Database mapping as much
as Database->Object mapping. It basically lets you set up simple
table->class, column->method, row->object mappings and everything just
does the right thing. But you can also model basic relationships between
tables, with, for example, the has_many method[1], which declares that
someone else is storing our primary key in their table, and create a
method which returns a list of all the associated objects.
So, if we have a 'track' table which says that the 'cd' column in that
table is a reference to the CD table, we would say
CD->has_many('tracks', CD::Track => 'cd');
This creates a method 'tracks' in the CD class that returns a list of
CD::Track objects related to a given CD.
In the case of Films and Actors from yesterday, this would end up sucking
in the entire database, Six Degrees of Kevin Bacon style, if we had to
pre-populate an entire data structure.
> If you really have no idea what data you're going to call until you hit the
> template, then this is a problem. I am willing to make all the decisions
> about what data will be available for the page in the perl code before the
> template is called, so simply returning the already loaded data is good
> enough for me. This makes my sense with my design philosophy (all brains
> are in perl code, and templates are nothing but layout).
In this example, however, I just want to pass a given Film object into a
template, as I have no idea what the designer is going to want to do
with it. She may want to show all the stars; or maybe just the first
three, but have a ("Also from") type link that you often get on the back of
video covers:
<h1>Moulin Rouge</h1>
<p>Starring
Ewan McGregor ("The Phantom Menace", "Trainspotting")
and Nicole Kidman ("Eyes Wide Shut", "Practical Magic")</p>
With Class::DBI they can do this easily, and I don't need to think about
it. I don't think this is particularly far removed from the "brains in
code, layout in template" philosophy. They just get passed a lot more
data, which just gets generated on demand, much of which is also objects
with more data, and so on. There's nothing complex in the example above:
<h1>[% film.name %]</h1>
<p>Starring
[% FOREACH star = film.stars %]
[% star.name %]
([% FOREACH otherfilm = star.films %]
"[% otherfilm.name %]"
[% END %])
[% END %]
</p>
OK, so you possibly need a bit of logic to make sure you don't print
the film they're already in, but that's fairly trivial. And possibly
something to only print the first "N" films; but for me that value of
"N" is a design decision, not a code one, and I don't want the designer
coming back to me every time they want to change it...
None of this is a problem. In fact Class::DBI makes all this trivial.
What is a problem though, is that they could theoretically also do
other things that I don't particularly want to allow. So I'd like some
nice way of putting a Facade in place that just restricts what methods
are accessible.
There doesn't appear to be anything that does what I want, so I'll
probably end up writing it, but I just thought I'd check first ...
Thanks,
Tony