[Dbix-class] best way to share schema elements?

Charlie Garrison garrison at zeta.org.au
Tue Nov 12 02:10:04 GMT 2013


Good afternoon,

I'll open with disclaimer that I don't really know the answer, 
but I asked the same question about 6 weeks ago with a new 
project (with lots of similar components to an old project), and 
I muddled through to answer it myself. I'll share my solution, 
and hope for more feedback from those who know better than me.

On 11/11/13 at 4:55 PM -0800, Seth Daniel 
<dbix-class at sethdaniel.org> wrote:

>If I'm wrong what is the best way to model having many shared
>columns/relationships over 2 or more tables without repeating 
>myself? Is there a way in DBIx::Class to model where an A and B 
>table "inherit"
>from a base table?  Is there a good way to do this in DBIx::Class?  Is
>this a good way to do this in DBix::Class?

I Moosified all my DBIC classes and used the standard `extends` 
functionality. In your example you will have 3 classes:

   Schema::RBase
   Schema::Result::TableA
   Schema::Result::TableB

TableA and TableB will both `extend` RBase. All the shared 
column definitions (& methods) go into RBase while everything 
table specific goes into one of the other classes.

In my case, I have same/similar classes in different projects, 
so I created new 'shared' module namespace (MyLib::Schema::RBase 
& RSBase). Multiple projects will use classes from the shared 
lib. Use `load_namespaces` to load classes from both the shared 
lib and your app's lib.

__PACKAGE__->load_namespaces(
     default_resultset_class =>   "+MyLib::Schema::RSBase",
     result_namespace        => [ '+MyLib::Schema::Result',    
'Result' ],
     resultset_namespace     => [ '+MyLib::Schema::ResultSet', 
'ResultSet' ],
);

It gets slightly tricky when defining relationships; some of 
them will refer to the shared lib namespace, rather than 
app/schema namespace; remember to check relationships carefully. 
Or just keep everything under MyApp and keep it simple.

__PACKAGE__->belongs_to( user => 'MyLib::Schema::Result::User', 'user_id');


>A not entirely unrelated question: is there a preferred way to share column
>definitions among non-related tables?  So if I want a username in one table
>and want the same definition for username in a different table is there a
>preferred way to share this definition among the result classes?  I can
>think of several ways to do it but wondering if there is a best practice
>wrt DBIx::Class.

Put the shared code/devinitions into a Moose role, and use that 
role `with` your result class. I did that to share the same 
(postal) address functionality across multiple classes. (I've 
become a big fan of Moose roles. :-) )

Again, I have no idea whether any of the above is best-practice 
(it was my personal best solution). I look forward to hearing 
further comments.

I'd be happy to receive some direction on where docco 
improvements could be made. I could not find the answer myself 
in docco, advent calendars, mailing list, etc. Before asking I 
thought I should clarify *what* I was asking, by which point I 
had answered it myself. But I spent way too much time doing so; 
I'm happy to contribute some docuentation; suggestions for 
what/where? Or does it already exist and I just couldn't find 
it, in which case some meta-docco may be needed.

Thanks,
Charlie

-- 
    Ꮚ Charlie Garrison ♊ <garrison at zeta.org.au>

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
〠  http://www.ietf.org/rfc/rfc1855.txt




More information about the DBIx-Class mailing list