[Dbix-class] Re: Reusing defined columns (inheritance?)

Hartmaier Alexander alexander.hartmaier at t-systems.at
Fri Jan 3 16:39:40 GMT 2014


On 2014-01-03 14:17, Dmitry Latin wrote:
>>> Yeah, but it works only with one parent. I want to subclass from 2 parent
>>> classes.
>> Use roles instead of multiple-inheritance, much easier to get right!
>>
> I would be very grateful to you if you could show me some code to make it
> work.
>
> All my attempts to do it (using Moose roles or inheritance via 'extends') was
> unsuccessful.
>
I looked at your github repo, some of the problems might comes because
your Result namespace is nested.
Put all classes directly in the Result namespace.

In our schema i have a result base class in Result::Parent::All which
e.g. loads components that are used by most tables like TimeStamp.

This is how it looks (the Result namespace is called Table in my schema):

package NAC::Model::DBIC::Table::Parent::All;
use Moose;
use MooseX::NonMoose;
use namespace::autoclean;

extends 'DBIx::Class::Core';

__PACKAGE__->load_components(
    qw(
        IntrospectableM2M
        InflateColumn::IP
        TimeStamp
        )
);

__PACKAGE__->table_class(
    'NAC::Model::DBIC::ResultSource::Table::Parent::All');

__PACKAGE__->table('dummy');
__PACKAGE__->resultset_class('NAC::Model::DBIC::ResultSet::Parent::All');

# disable cascade_delete by default
around qw( might_have has_one has_many ) => sub {
    my $orig  = shift;
    my $class = shift;

    # copy to avoid side effects cause by modifying the input params
    my @params = @_;
    my ( $rel, $f_class, $cond, $attrs ) = @params;

    $attrs ||= {};
    $attrs->{cascade_delete} = 0
        unless exists $attrs->{cascade_delete};
    $params[3] = $attrs;

    $class->$orig(@params);
};

# to allow subclasses use around method modifiers
sub FOREIGNBUILDARGS {
    shift;
    return @_;
}

__PACKAGE__->meta->make_immutable;

1;

Then I have a result role that adds four columns to a table:

package NAC::Model::DBIC::ResultRole::Auditable;
use base DBIx::Class;

use Class::C3::Componentised::ApplyHooks
    -after_apply => sub {
        my ($class, $component) = @_;

        $class->load_components(qw( UserStamp ));

        $class->add_columns(
            "create_datetime",
            {   data_type     => "DATETIME",
                is_nullable   => 0,
                timezone      => "UTC",
                set_on_create => 1,
            },
            "create_user",
            {   data_type            => "NUMBER",
                is_foreign_key       => 1,
                is_nullable          => 1,
                size                 => 6,
                store_user_on_create => 1,
            },
            "update_datetime",
            {   data_type     => "DATETIME",
                is_nullable   => 0,
                timezone      => "UTC",
                set_on_create => 1,
                set_on_update => 1,
            },
            "update_user",
            {   data_type            => "NUMBER",
                is_foreign_key       => 1,
                is_nullable          => 1,
                size                 => 6,
                store_user_on_create => 1,
                store_user_on_update => 1,
            },
        );

        $class->belongs_to(
            "rel_create_user",
            "NAC::Model::DBIC::Table::Nacuser",
            "create_user",
            { join_type => "LEFT" },
        );

        $class->belongs_to(
            "rel_update_user",
            "NAC::Model::DBIC::Table::Nacuser",
            "update_user",
            { join_type => "LEFT" },
        );
    }, qw();

1;

=head1 NAME

NAC::Model::DBIC::ResultRole::Auditable - result role that adds audit
columns
and relationships.

=cut

=head1 SYNOPSIS

    # this has to go after ->table
    __PACKAGE__->load_components(qw(
+NAC::Model::DBIC::ResultRole::Auditable ));

=cut


I don't remember why Class::C3::Componentised::ApplyHooks was necessary
to make it work as I have other roles that don't require it but I think
it has to do with adding relationships as well.


And in one of the result classes I apply the role just after the
add_columns call:

__PACKAGE__->load_components(qw(
+NAC::Model::DBIC::ResultRole::Auditable ));

HTH


*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
T-Systems Austria GesmbH Rennweg 97-99, 1030 Wien
Handelsgericht Wien, FN 79340b
*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
Notice: This e-mail contains information that is confidential and may be privileged.
If you are not the intended recipient, please notify the sender and then
delete this e-mail immediately.
*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*



More information about the DBIx-Class mailing list