[Catalyst] Catalyst::Model::DBIC::Schema and ACCEPT_CONTEXT -- current user in model

Bill Moseley moseley at hank.org
Fri May 14 20:59:27 GMT 2010


On Thu, May 13, 2010 at 2:54 PM, Kieren Diment <diment at gmail.com> wrote:

>  sub ACCEPT_CONTEXT {
>     my ($self, $c ) =3D @_;
>     my $new =3D $self->meta->clone_object($self, arg =3D>
> $c->stash->{something});
>     return $new;
>  }
>

Hum, I'm not clear how that works with Catalyst::Model::DBIC::Schema,
because I want to be able to call "current_user" on any row object.
 $track->current_user.


Again, I have some aversion to saving a current user in my model.  That was
more my question.  Getting something to work is easy enough, just not sure
it's the best approach.

For example:

In my Music::Schema base class I add an accessor:

 has 'current_user' =3D> ( is =3D> 'rw'  );

Then in my Result base class add a convenience method:

 sub current_user { return shift->result_source->schema->current_user }

Now, I might want to have a method $track->can_user_access so in my Track
class:

sub can_user_access {
    my ( $track, $current_user ) =3D @_;

    # Use saved user if one not passed.
    $current_user ||=3D $track->current_user || die 'no current_user';
    ...
    return $has_access;


Finally, in Catalyst my Model class would then look like:

package MyApp::Model::Music;
use Moose;
extends 'Catalyst::Model::DBIC::Schema';
use namespace::autoclean;

before 'ACCEPT_CONTEXT' =3D> sub {
    my ( $self, $c  ) =3D @_;
    $self->schema->current_user( $c->current_user );

};


 __PACKAGE__->meta->make_immutable;
1;


That implementation is simple enough, but not clear is it's the best
approach.


Backing up, the issue that came up is I have a base class used for setting
up very common actions for an API.  The controllers for, say,
/music/track/$id are set up with configuration only:

package MyApp::Controller::Music::Track;
BEGIN { extends 'MyApp::Controller::API' }
__PACKAGE__->config(
    return_colums =3D> [qw/ id track_name position can_user_access /],
);
1;


The controller base class then builds a response that includes those columns
and methods.  But, the base class doesn't know when to pass in the current
user to a method (e.g. for can_user_access).

So, I either extend the config to tell the base class to pass the current
user to some methods:

pass_user_to_meethod =3D> [ 'can_user_access' ]


Or I use something like ACCEPT_CONTEXT to set the current user in the
schema.

Better ideas?


This is going to be a killer Music app.  I just hope CDs don't go out of
style.



-- =

Bill Moseley
moseley at hank.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20100514/fc167=
5f4/attachment.htm


More information about the Catalyst mailing list