DBIx::Class::Wrapper - A Moose role to allow your business model to wrap business code around a dbic model.
This package allows you to easily extend your DBIC Schema by Optionally wrapping its resultsets and result objects in your own business classes.
package My::Model; use Moose; with qw/DBIx::Class::Wrapper/; 1
Later
my $schema = instance of DBIx schema my $app = My::Model->new( { dbic_schema => $schema } ); ## And use the dbic resultsets-ish methods. my $products = $app->dbic_factory('Product'); ## Get a new instance of the Product resultset. ## Use classic DBIC methods as usual. my $p = $products->find(2); my $blue_ps = $products->search({ colour => blue });
First you need a DBIC factory that will wrap the raw dbic object into your own class of product
package My::Model::Wrapper::Factory::Product; use Moose; extends qw/DBIx::Class::Wrapper::Factory/ ; sub wrap{ my ($self , $o) = @_; return My::Model::O::Product->new({o => $o , factory => $self }); } 1;
Then your Product business object class
package My::Model::O::Product; use Moose; has 'o' => ( isa => 'My::Schema::Product', ## The raw DBIC object class. is => 'ro' , required => 1, handles => [ 'id' , 'name', 'active' ] ## handles standard properties ); ## A business method sub activate{ my ($self) = @_; $self->o->update({ active => 1 }); }
Then from your main code, continue using the Product resultset as normal.
my $product = $app->dbic_factory('Product')->find(1); ## But you can do $product->activate(); ## so now $product->active() == 1;
Let's say you decide that from now, the bulk of your application should access only active products, leaving unlimited access to all product to a limited set of places.
package My::Model::Wrapper::Factory::Product; use Moose; extends qw/DBIx::Class::Wrapper::Factory/; sub build_dbic_rs{ my ($self) = @_; ## Note that you can always access your original business model ## from a factory (method bm). return $self->bm->dbic_schema->resultset('Product')->search_rs({ active => 1}); ## This is a simple example. You can restrict your products set ## according to any current property of your business model for instance. } sub wrap{ .. same .. } 1;
Everywhere your application uses $app->dbic_factory('Product') is now restricted to active products only.
Surely you want admin parts of your application to access all products. So here's a very basic AllProducts:
package My::Model::Wrapper::Factory::AllProduct; use Moose; extends qw/My::Model::Wrapper::Factory::Product/; sub build_dbic_rs{ my ($self) = @_; ## Some extra security. unless( $self->bm->current_user()->is_admin() ){ confess "Sorry you cant access that"; } return $self->bm()->dbic_schema->resultset('Product')->search_rs(); }
Until now, all your custom factories were named My::Model::Wrapper::Factory::<something>.
If you want to customise the base class of those custom factories, you can do so by overriding the method _build_dbic_factory_baseclass in your model:
package My::Model; use Moose; with qw/DBIx::Class::Wrapper/; sub _build_dbic_factory_baseclass{ return 'My::Model::DBICFactory'; # for instance. }
Then implement your factories as subpackages of My::Model::DBICFactory
Returns a new instance of DBIx::Class::Wrapper::Factory that wraps around the given DBIC ResultSet name if such a resultset exists. Dies otherwise.
Additionaly, you can set a ad-hoc resulset if you want to locally restrict your original resultset.
usage:
my $f = $this->dbic_factory('Article'); my $f = $this->dbic_factory('Article' , { dbic_rs => $schema->resultset('Article')->search_rs({ is_active => 1 }) });
To install DBIx::Class::Wrapper, copy and paste the appropriate command in to your terminal.
cpanm
cpanm DBIx::Class::Wrapper
CPAN shell
perl -MCPAN -e shell install DBIx::Class::Wrapper
For more information on module installation, please visit the detailed CPAN module installation guide.