[Dbix-class] Caching of related resultsets
Bernhard Graf
dbic1 at augensalat.de
Fri Oct 6 22:06:04 CEST 2006
On Friday 06 October 2006 18:42, Bernhard Graf wrote:
> I have a user - roles setup similar to
> Catalyst::Manual::Tutorial::Authentication.
>
> My application quite often queries roles for the authenticated user
> ($c->user->obj) within one HTTP query.
>
> For this purpose I defined a method in the DBIC user class like this:
>
> sub has_role {
> my ($self, $name) = @_;
> $self->roles->find($role);
> }
>
> To save db access I'd prefer caching $user->roles->all inside the
> user object ($c->user->obj) in the first call of has_role() and
> access roles in subsequent calls to has_role() from this cache.
>
> Is this possible?
Meanwhile I can answer my own question.
DBIx::Class::Manual::FAQ took me on the right track:
How do I store my own (non-db) data in my DBIx::Class objects?
You can add your own data accessors to your classes.
The resulting code looks like this:
(Note: My roles table has only one column "id" that is primary key and
contains the profile name)
package MyApp::DB::User;
use base 'DBIx::Class';
__PACKAGE__->mk_classaccessor('role_ids_cache');
[...]
sub role_ids {
my $self = shift;
return $self->role_ids_cache([map { $_->id} $self->roles->all])
unless $self->role_ids_cache;
$self->role_ids_cache;
}
sub has_role {
my ($self, $name) = @_;
foreach my $role (@{$self->role_ids}) {
return 1 if $role eq $name;
}
return;
}
Now only the first call to $user->has_role($name) (or $user->role_ids())
does an SQL query, subsequent calls fetch from cache.
Note 2: I started with
__PACKAGE__->mk_classaccessor('role_ids');
sub role_ids {
my $self = shift;
return $self->_role_ids_accessor([map { $_->id} $self->roles->all])
unless $self->_role_ids_accessor;
$self->_role_ids_accessor;
}
sub has_role {
...
but for some reason, that I don't understand my own sub role_ids never
got called.
--
Bernhard Graf
More information about the Dbix-class
mailing list