DBIx-Class-Wrapper
view release on metacpan or search on metacpan
lib/DBIx/Class/Wrapper.pm view on Meta::CPAN
=head2 Your own specialised resultset
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();
}
=head2 Changing the factory base class.
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
=cut
has 'dbic_schema' => ( is => 'rw' , isa => 'DBIx::Class::Schema' , required => 1 );
has 'dbic_factory_baseclass' => ( is => 'ro' , isa => 'Str' , lazy_build => 1);
has '_dbic_dbic_fact_classes' => ( is => 'ro' , isa => 'HashRef[Bool]' , lazy_build => 1);
sub _build_dbic_factory_baseclass{
my ($self) = @_;
return ref ($self).'::Wrapper::Factory';
}
sub _build__dbic_dbic_fact_classes{
my ($self) = @_;
my $baseclass = $self->dbic_factory_baseclass();
my $res = {};
my $mp = Module::Pluggable::Object->new( search_path => [ $baseclass ]);
foreach my $candidate_class ( $mp->plugins() ){
Class::Load::load_class( $candidate_class );
# Code is loaded
unless( $candidate_class->isa('DBIx::Class::Wrapper::Factory') ){
warn "Class $candidate_class does not extend DBIx::Class::Wrapper::Factory.";
next;
}
# And inherit from the right class.
$res->{$candidate_class} = 1;
}
return $res;
}
=head1 METHODS
=head2 dbic_factory
Returns a new instance of L<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 }) });
=cut
sub dbic_factory{
my ($self , $name , $init_args ) = @_;
unless( defined $init_args ){
$init_args = {};
}
unless( $name ){
confess("Missing name in call to dbic_factory");
}
my $class_name = $self->dbic_factory_baseclass().'::'.$name;
## Build a class dynamically if necessary
unless( $self->_dbic_dbic_fact_classes->{$class_name} ){
## We need to build such a class.
Moose::Meta::Class->create($class_name => ( superclasses => [ 'DBIx::Class::Wrapper::Factory' ] ));
$self->_dbic_dbic_fact_classes->{$class_name} = 1;
}
## Ok, $class_name is now there
## Note that the factory will built its own resultset from this model and the name
( run in 1.570 second using v1.01-cache-2.11-cpan-39bf76dae61 )