How to set up DBIx :: Class schema with Moose - specific guide

It was pretty hard for me to find information on how to assemble the DBIx::Class schema structure using Moose . How to do it correctly (essentially working) and in modern Perl (good style, fast, without warning)?

These are my goals:

  • follow Moose Moose::Manual::BestPractices , especially:
    • use namespace::autoclean and
    • use __PACKAGE__->meta->make_immutable .
  • use common base classes for Result and ResultSet
  • when using any magic tricks there is a comment explaining them (during the research I found a guide suggesting sub BUILDARGS { $_[2] } , explainable not to ask )
  • move common code, for example. MooseX::NonMoose (if necessary) or __PACKAGE__->load_components , into a common base class, as suggested by DBIx::Class::Manual::Cookbook

These are the problems I encountered:

  • when using __PACKAGE__->meta->make_immutable I got warnings like Not inlining 'new' for MyApp::Schema::Result::MyTable since it is not inheriting the default Moose::Object::new
  • when transferring all calls to __PACKAGE__->load_components to the Result base class my datetime columns do not accumulate
+6
source share
2 answers

Solutions to problems:

  • make_immutable conflicts with the constructor non Moose new : this is automatically handled use MooseX::NonMoose ; unlike its documentation, no additional arguments or options are required; that DBIx::Class::Schema does not have a new method, and therefore MyApp::Schema does not need this helper
  • InflateColumn::DateTime does not inflate when loaded into the base class: this was caused by the order of the components specified in load_components() ; the documentation should not hint that the order should matter, and I filed a bug report about it; reordering helped

With the solutions above, my DBIx :: Class example with Moose looks like this:

Schema Class:

 package MyApp::Schema; use Moose; # we want Moose use MooseX::MarkAsMethods autoclean => 1; # this helps removing unused symbols like Moose keywords # do NOT 'use MooseX::NonMoose' here because Schema class has no 'new' method extends 'DBIx::Class::Schema'; # the Moose way of inheritance # load all table modules automatically __PACKAGE__->load_namespaces( # ResultSet class for tables without custom ResultSet class # (would be DBIx::Class::ResultSet otherwise) default_resultset_class => '+MyApp::Schema::ResultSet', ); # tell Moose this class is finished: some Moose stuff is removed and things go faster __PACKAGE__->meta->make_immutable; 1; 

Generic Result Base Class:

 # a base class for all table class of this app package MyApp::Schema::Result; use Moose; use MooseX::MarkAsMethods autoclean => 1; use MooseX::NonMoose; # this is important for correctly handling DBIx::Class' new extends 'DBIx::Class::Core'; # this is the right place to implement generic stuff # DBIx::Class::Cookbook recommends loading components in a central place __PACKAGE__->load_components(qw/ InflateColumn::DateTime ... /); __PACKAGE__->meta->make_immutable; 1; 

Generic ResultSet base class:

 package MyApp::Schema::ResultSet; use Moose; use MooseX::MarkAsMethods autoclean => 1; use MooseX::NonMoose; extends 'DBIx::Class::ResultSet'; __PACKAGE__->meta->make_immutable; 1; 

Example ResultSet class for the table my_table :

 package MyApp::Schema::ResultSet::MyTable; use Moose; use MooseX::MarkAsMethods autoclean => 1; extends 'MyApp::Schema::ResultSet'; sub oldest { my $self = shift; $self->search({}, {order_by => {-ASC => 'date'}})->first; } __PACKAGE__->meta->make_immutable; 1; 

Example Result class for table my_table :

 package MyApp::Schema::Result::MyTable; use Moose; use MooseX::MarkAsMethods autoclean => 1; extends 'MyApp::Schema::Result'; __PACKAGE__->table("my_table"); __PACKAGE__->add_columns( id => {data_type => "integer", is_auto_increment => 1}, date => {data_type => "date"}, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->meta->make_immutable; 1; 
+7
source

What is wrong with use_moose in DBIx :: Class :: Schema :: Loader ? (e.g. dbicdump -o use_moose=1 MyApp::Schema <dsn> <user> <pass>

This is what use_moose=1 in DBIx::Class::Schema::Loader 0.07039 generates for the schema:

 use utf8; package MyApp::Schema; # Created by DBIx::Class::Schema::Loader # DO NOT MODIFY THE FIRST PART OF THIS FILE use Moose; use MooseX::MarkAsMethods autoclean => 1; extends 'DBIx::Class::Schema'; __PACKAGE__->load_namespaces; # Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-03-19 22:50:18 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7Hx1RMeFsxCqo5YaLOzPdQ # You can replace this text with custom code or comments, and it will be preserved on regeneration __PACKAGE__->meta->make_immutable(inline_constructor => 0); 1; 

And the result class:

 use utf8; package MyApp::Schema::Result::Example; # Created by DBIx::Class::Schema::Loader # DO NOT MODIFY THE FIRST PART OF THIS FILE use strict; use warnings; use Moose; use MooseX::NonMoose; use MooseX::MarkAsMethods autoclean => 1; extends 'DBIx::Class::Core'; ...yadda... # Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-03-19 22:50:18 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yTmu6Rh9TAEwxqgDClBdtg # You can replace this text with custom code or comments, and it will be preserved on regeneration __PACKAGE__->meta->make_immutable; 1; 

And here is the documentation for creating the Moosified ResultSet class

It looks like it has extraneous use strict and use warnings , but not biggie. The good part is that if something changes, we hope that DBIx::Class::Schema::Loader will be updated to take into account any necessary changes.

Sorry if I miss the point.

+3
source

All Articles