[Dbix-class] Issues with the hook-in point of ResultSetManager

Shevek shevek at anarres.org
Sun Apr 16 13:42:51 CEST 2006


ResultSetManager hooks 'table()', which leads to some weaknesses.
Workaround attached. A better hook-in point should be found. I do not
suggest one.

The long version, with asides:

I use Loader to get the column definitions and load my external classes.
My external classes then set up all the relationships, and define many
object and ResultSet methods.

Here is an external class:

package Foo;

# This loads into the _resultset namespace OK
__PACKAGE__->load_resultset_component(qw/+Baz/);

# This should get trapped by RSM
sub bar : ResultSet {
}

However, RSM traps at 'sub table'. table() is called by Loader. A brief
aside: Let's look at a normal class definition:


package Foo;

use base 'DBIx::Class::ResultSetManager';

__PACKAGE__->table('foo');
....

sub foo : ResultSet {
}

...


So Perl does two passes: one to compile, during which attributes are
registered and cached. Then it goes back and calls ->table().

Using Loader with external class definitions changes this, effectively
producing:

BEGIN { __PACKAGE__->table('foo') }

Now the compiler hasn't reached/registered 'sub foo' so it never gets
transferred to the _attr_cache and hence to the ResultSet.

However, if we later call __PACKAGE__->_register_attributes() ourselves,
everything behaves fine.

Therefore, I now have a Loader which looks like:


      9 __PACKAGE__->loader(new DBIx::Class::Schema::Loader::Pg(
.............
     13 #   components          => [ qw/ResultSetManager/ ],
     14     resultset_components=> [ qw/+Karma::DB::RS::Retrieve/ ],
     15     left_base_classes   => 'Karma::DB::Live::Base',
     16     schema              => 'Karma::DB::Live',
     17 #   relationships       => 1,
     18 #   debug               => 1,
     19 ));
     20 __PACKAGE__->loader->load();
     21 
     22 for (keys %{ __PACKAGE__->class_mappings }) {
     23     # Something in ResultSetManager
     24     $_->_register_attributes();
     25 }

which is a bit odd, but now works as expected, largely due to the
foresight shown by the author of RSM when checking the existence etc of
subrefs.

This _could_ be fixed by modifying loader, but I do think a better
solution would be to hook ResultSetManager into some sort of 'schema
post-compile' stage. The choice of table() seems a little arbitrary.

I note also that in my left_base_class, I can neither define resultset
components nor methods tagged as :ResultSet. I hope that a more elegant
future development of ResultSetManager would permit this.

S.

-- 
Shevek <shevek at anarres.org>




More information about the Dbix-class mailing list