views:

308

answers:

3

It seems kind of a pain to have my Moose classes. Then to use DBIx::Class to get a result set..then to manually map my result set to the moose classes.

+2  A: 

You can use Moose with DBIC no problem. Actually I enjoy using MooseX::Declare since I find the extended syntax is very useful when designing solid public apis, for example:

use MooseX::Declare;
class MyApp::Schema::Result::Geo::Division
 extends MyApp::Schema::Result {
    use Locale::Geocode::Division;
 __PACKAGE__->table('division');
 __PACKAGE__->add_columns(
  fk_territory_id => {
   data_type => 'char',
   size => '36',
  },
  division_id => {
   data_type => 'char',
   size => '36',
  },
  code => {
            data_type => 'varchar',
   size => '5',
  },
     created => {
   data_type => 'datetime',
   set_on_create => 1,
  },
 );

 __PACKAGE__->set_primary_key('fk_territory_id','division_id');
 __PACKAGE__->uuid_columns('division_id');
    __PACKAGE__->add_unique_constraint(['fk_territory_id','code']);

 __PACKAGE__->belongs_to(
  territory => 'MyApp::Schema::Result::Geo::Territory',
  {'foreign.territory_id' => 'self.fk_territory_id'},
 );
    method as_geocode_division {
        Locale::Geocode::Division->new($self->code);
    }     
 __PACKAGE__->meta->make_immutable(inline_constructor => 0);
} 1;
How would you declare the Moose attributes if the schema is already defined by the DB (that is, DBIx::Class reads in the schema, rather than it being defined by the method calls you do above)?
Ether
You mean *runtime* schema loading? Not gonna play nice. :)
hobbs
A: 

It sounds like you're describing exactly what I wrote recently in order to map Moose attribute values onto Rose::DB::Object values (with the db object and objectmanager contained in private attributes) and vice versa. I originally used triggers around each Moose attribute to write to the Rose object immediately, but later abandoned that approach and lazily-wrote the values only when needed (i.e. at the time of a ->save() operation). I implemented it using a few roles and a sugar class which automatically installed an attribute trait indicating "I am a table field" for the relevant attributes.

But don't do what I did -- just use DBIx::Class directly! The next major version is being rewritten in Moose anyway, so I hear.

Ether
*The next major version is being rewritten in Moose anyway, so I hear.* that's been going around for years.
Evan Carroll
Matt had an inventive talk about it at Perl Oasis last month.
perigrin
+4  A: 

If you're having to map back and forth between Moose classes and a DBIC schema, you may want to look at a persistent object store like KiokuDB instead.

You lose some of the features of a Relational Database, especially if you have an existing schema but you gain a lot of features the main one being quiet mapping between the data-store and your Object model. The DBI back-end for KiokuDB is probably the best example of this trade off. The database is highly de-normalized, but that's because it's working as effectively a key-store.

KiokuDB however can work with storage engines that are optimized for this kind of data. It supports several of the current crop of "NoSQL" celebrities including CouchDB, and MongoDB. It also supports the older fan favorite BerkelyDB.

Kioku isn't the answer for every problem, but it is used quite successfully for Parking Mobility to handle all the data storage seamlessly.

perigrin
+1 for beating me to the mention of KiokuDB.
Dave Sherohman