[Dbix-class] compoase_namespace, add_column, and result_source_instance

Christopher H. Laco claco at chrislaco.com
Sat Jul 8 08:39:16 CEST 2006


I've been trying to track down an issue that has me flummoxed. Again, I
apologize for the late night rambling.

The basic symptom is that if I add a column to a cloned schema (cloned
via compose_namespace), it gets added to both the cloned schema object,
and the original schema object.

At first, I was adding column using:

    my $clone = $schema->compose_namespace('Foo');
    $clone->source('Items')->add_column('custom');

This adds the column to the source:

    print $clone->source('Items')->columns;
    # custom, ...other cols...

but the column will not appear in:

    $clone-class('Items')->columns;

I understand why for the most part. Since I'm adding a column after
connect(), class is left untouched, and as a side issue, the accessor
for 'custom' does not appear in $schema->class('Item').

So, the next suggestion was to register the column:

    $clone->source('Items')->add_column('custom');
    $clone->class('Items')->register_column(
	'custom' => $clone->source('Items')->column_info('custom')
    );

This had no effect. The custom column was in source('Items')->columns,
but not in class('Items')->columns.

So, the next thing I tried was calling add_columns to both the source,
and class:

    $clone->source('Items')->add_column('custom');
    $clone->class('Items')->add_column('custom');

At first glance, this worked:

    $clone->source('Items')->columns;
    $clone->class('Items')->columns;

both contained the custom column, and the class contained the accessor
for custom. I would expect it to work because $schema->class('Items')
and $clone->class('Items') return two different classes.

Unfortunately, I soon realized that:

    $schema->class('Items')->columns;
    $schema->source('Items')->columns;

now had a 'custom' column as well. After a few rounds of Data::Dump, I
finally realized what my problem was:

    use Handel::Cart::Schema;
    my $schema = Handel::Cart::Schema->connect($ENV{HandelDBIDSN});
    my $new = $schema->compose_namespace('Foo');

    print $schema->class('Items')->result_source_instance, "\n";
    print $new->class('Items')->result_source_instance, "\n";

This prints the same address/result_source_instance. So, even after a
clone operation on a schema, the result_source_instance remains the
same, even through it is proxying for two distinct resultsource classes
with the aid of compose_namespace.

That's probably also why the call to
$clone->class('Items')->register_column failed; presumably it's going to
the wrong resultsource class...the original, instead of the new source
class generated by compose_namespace.

If any of this makes sense, congrats. :-)
What's the way out of this mess?

When a schema is cloned into a new one useing compose_namespace,
shouldn't the result_source_instance in the new classes e repointed to
the new copy of the resultsource instances from source() ?

-=Chris


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: OpenPGP digital signature
Url : http://lists.rawmode.org/pipermail/dbix-class/attachments/20060708/f280c010/attachment.pgp 


More information about the Dbix-class mailing list