DBIx-Class-ResultSource-MultipleTableInheritance

 view release on metacpan or  search on metacpan

README.html  view on Meta::CPAN

<p>This only works with PostgreSQL at the moment. It has been tested with
PostgreSQL 9.0, 9.1 beta, and 9.1.</p>
<p>There is one additional caveat: the &quot;parent&quot; result classes that you
defined with this resultsource must have one primary column and it must
be named &quot;id.&quot;</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
    {
        package Cafe::Result::Coffee;</pre>
<pre>
        use strict;
        use warnings;
        use parent 'DBIx::Class::Core';
        use aliased 'DBIx::Class::ResultSource::MultipleTableInheritance'
            =&gt; 'MTI';</pre>
<pre>
        __PACKAGE__-&gt;table_class(MTI);
        __PACKAGE__-&gt;table('coffee');
        __PACKAGE__-&gt;add_columns(
            &quot;id&quot;, { data_type =&gt; &quot;integer&quot; },
            &quot;flavor&quot;, {
                data_type =&gt; &quot;text&quot;,
                default_value =&gt; &quot;good&quot; },
        );</pre>
<pre>
        __PACKAGE__-&gt;set_primary_key(&quot;id&quot;);</pre>
<pre>
        1;
    }</pre>
<pre>
    {
        package Cafe::Result::Sumatra;</pre>
<pre>
        use parent 'Cafe::Result::Coffee';</pre>
<pre>
        __PACKAGE__-&gt;table('sumatra');</pre>
<pre>
        __PACKAGE__-&gt;add_columns( &quot;aroma&quot;,
            { data_type =&gt; &quot;text&quot; }
        );</pre>
<pre>
        1;
    }</pre>
<pre>
    ...</pre>
<pre>
    my $schema = Cafe-&gt;connect($dsn,$user,$pass);</pre>
<pre>
    my $cup = $schema-&gt;resultset('Sumatra');</pre>
<pre>
    print STDERR Dwarn $cup-&gt;result_source-&gt;columns;</pre>
<pre>
        &quot;id&quot;
        &quot;flavor&quot;
        &quot;aroma&quot;
        ..</pre>
<p>Inherit from this package and you can make a resultset class from a view, but
that's more than a little bit misleading: the result is <strong>transparently
writable</strong>.</p>
<p>This is accomplished through the use of stored procedures that map changes
written to the view to changes to the underlying concrete tables.</p>
<p>
</p>
<hr />
<h1><a name="why">WHY?</a></h1>
<p>In many applications, many classes are subclasses of others. Let's say you
have this schema:</p>
<pre>
    # Conceptual domain model</pre>
<pre>
    class User {
        has id,
        has name,
        has password
    }</pre>
<pre>
    class Investor {
        has id,
        has name,
        has password,
        has dollars
    }</pre>
<p>That's redundant. Hold on a sec...</p>
<pre>
    class User {
        has id,
        has name,
        has password
    }</pre>
<pre>
    class Investor extends User {
        has dollars
    }</pre>
<p>Good idea, but how to put this into code?</p>
<p>One far-too common and absolutely horrendous solution is to have a &quot;checkbox&quot;
in your database: a nullable &quot;investor&quot; column, which entails a nullable
&quot;dollars&quot; column, in the user table.</p>
<pre>
    create table &quot;user&quot; (
        &quot;id&quot; integer not null primary key autoincrement,
        &quot;name&quot; text not null,
        &quot;password&quot; text not null,
        &quot;investor&quot; tinyint(1),
        &quot;dollars&quot; integer
    );</pre>
<p>Let's not discuss that further.</p>
<p>A second, better, solution is to break out the two tables into user and
investor:</p>
<pre>
    create table &quot;user&quot; (
        &quot;id&quot; integer not null primary key autoincrement,
        &quot;name&quot; text not null,
        &quot;password&quot; text not null
    );</pre>
<pre>
    create table &quot;investor&quot; (
        &quot;id&quot; integer not null references user(&quot;id&quot;),
        &quot;dollars&quot; integer



( run in 1.103 second using v1.01-cache-2.11-cpan-5b529ec07f3 )