in reply to Re: Moose + ORM
in thread Moose + ORM

This is not the right way to do this, a role should not export new sugar into the class. I think perhaps you want MooseX::Roles::Parameterized instead.

-stvn

Replies are listed 'Best First'.
Re^3: Moose + ORM
by stvn (Monsignor) on Jul 23, 2009 at 21:16 UTC

    And here is what it might look like ...

    package Table; use MooseX::Role::Parameterized; parameter table_name => ( isa => 'Str', required => 1, ); role { my $p = shift; my $table = $p->table_name; my $dbh = DBI->connect( ... ); my $sth = $dbh->selectall_arrayref( "describe $table" ); my @columns = ... do DBI magic here ... foreach my $col (@column) { has $col->{name} => ( is => 'rw', isa => $col->{type}, default => $col->{default}, ); } }; package MyTable; use Moose; with 'Table' => { table_name => 'my_table' };

    -stvn
      Thank you very much for this. I tinkered around with my code last night and realized that I should not be exporting like that. This is what I came up with: I wonder what kind of contracts I am breaking with any class that wants to use this ... but it seems to work. The trick is loading the data into the object after it has been defined.

      Question if you have the gumption ... how would you handle loading the data? How would you pass the unique identifier of the database table row to be loaded into your MooseX::Role::Parameterized solution? That's the trouble I seem to have now, and hence why I added the Table::Loader role.

      Thanks again!

        Question if you have the gumption ... how would you handle loading the data?

        Honestly, I would have used DBIx::Class or Fey::ORM. I wrote my own ORM years ago when SPOPS was state of the art and Class::DBI was still very much an ugly/dirty hack. I won't ever write one again, it is a solved problem and I have no interest in re-inventing that wheel.

        First, it is very much not recommended to put a BUILD method in roles because it could get overridden by a local class version. You should do a before/after/around for BUILD instead, which will do what you want it to do.

        Second, I would get rid of the BUILD method anyway and put the load function into the role and then call  MyTable->load( id => 1 ) to get things from the DB, because using new to fetch from the database is misleading since it is not creating a new instance, but loading an old one.

        -stvn
      1. The issues of connecting to a database need to be resolved in a configurable flexible way
      2. "The future of DBIx::Class talk" covers that syntax (32 minutes in) Maybe you could contribute to that.
      3. Joins need to be solved?
      4. If you just want an easy access to one table, maybe Tie::DBI is enough?
        1. I have #1 covered for my needs, but going forward as a CPAN module then yes, this needs to be solved.
        2. I'll check out the video.
        3. this can be solved by someone else, thank you. :) I personally think this is mostly a waste of time and can be handled by writing custom methods with optimized SQL. But when the day comes that someone actually solves this problem in a 100% reusable manner, I'll use it. :)
        4. this seems very unappealing -- the idea is to make a Moose role. Feel free to write an example that works with Moose if you really think I missed the point.