FAQ
Hi there,

I'm basically wanting to write a simple log function which logs hits on my
website as entries in a database (automatically adding $c->user->{id} and
$c->req->referrer etc), but to do so I want to use a model (I think). Any
ideas how I can just say $c->model('Log')->info("foo") and automatically get
$c passed in? I think I could have sth like:

package MyApp::Model::Log;
use base 'Catalyst::Model';

my $last_c;

sub ACCEPT_CONTEXT {
my ($self, $c) = @_;
$last_c = $c;
}

sub info {
my ($self, $msg) = @_
my $c = $last_c;
...
}

but this seems pretty messy...

Mark

Search Discussions

  • Lorn at Dec 27, 2006 at 12:55 pm
    you can passa the $c from controller to model
    $c->model(foo)->bar($c,$foobar);
    On 12/27/06, Mark Zealey wrote:

    Hi there,

    I'm basically wanting to write a simple log function which logs hits on my
    website as entries in a database (automatically adding $c->user->{id} and
    $c->req->referrer etc), but to do so I want to use a model (I think). Any
    ideas how I can just say $c->model('Log')->info("foo") and automatically
    get
    $c passed in? I think I could have sth like:

    package MyApp::Model::Log;
    use base 'Catalyst::Model';

    my $last_c;

    sub ACCEPT_CONTEXT {
    my ($self, $c) = @_;
    $last_c = $c;
    }

    sub info {
    my ($self, $msg) = @_
    my $c = $last_c;
    ...
    }

    but this seems pretty messy...

    Mark

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/


    --
    Lorn
    - Slackware Linux
    www.slackwarezine.com.br
    - http://lornlab.org
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20061227/963fb3fe/attachment.htm
  • John Napiorkowski at Dec 27, 2006 at 3:02 pm

    --- Lorn wrote:

    you can passa the $c from controller to model
    $c->model(foo)->bar($c,$foobar);
    I'd vote for this method over setting the context,
    since one of the goals of a model is to not care about
    how or when it's called, that way you are encouraging
    yourself to not build a fragile application where
    everything is interdependent. Actually I'd take it a
    step further and only pass the stuff from the context
    that you need, like $c->request if you need the
    request object, etc.

    That being said I have used the method suggested by
    another responder for grabbing the context, mostly so
    that I can do debugging inside the model
    ($c->log->...). If there was better way to access the
    log object from views and models that don't require
    getting the context or getting $c->log than I am sure
    I'd never need it.

    A seemless way to share $c->log with DBIx::Class
    objects would also be nice.

    Also, as an aside, if you are building a custom logger
    it might be more fun to create your own logger object
    so that you can do $c->log->mylogger(...), or I
    believe you can use the Log4Perl catalyst plugin and
    configure it to log to a databse. That way you can
    skip the whole creating a custom model for this need.

    --john
    On 12/27/06, Mark Zealey wrote:

    Hi there,

    I'm basically wanting to write a simple log
    function which logs hits on my
    website as entries in a database (automatically
    adding $c->user->{id} and
    $c->req->referrer etc), but to do so I want to use
    a model (I think). Any
    ideas how I can just say
    $c->model('Log')->info("foo") and automatically
    get
    $c passed in? I think I could have sth like:

    package MyApp::Model::Log;
    use base 'Catalyst::Model';

    my $last_c;

    sub ACCEPT_CONTEXT {
    my ($self, $c) = @_;
    $last_c = $c;
    }

    sub info {
    my ($self, $msg) = @_
    my $c = $last_c;
    ...
    }

    but this seems pretty messy...

    Mark

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo:
    http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/


    --
    Lorn
    - Slackware Linux
    www.slackwarezine.com.br
    - http://lornlab.org
    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo:
    http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/

    __________________________________________________
    Do You Yahoo!?
    Tired of spam? Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com
  • Ash Berlin at Dec 27, 2006 at 1:01 pm

    Mark Zealey wrote:
    Hi there,

    I'm basically wanting to write a simple log function which logs hits on my
    website as entries in a database (automatically adding $c->user->{id} and
    $c->req->referrer etc), but to do so I want to use a model (I think). Any
    ideas how I can just say $c->model('Log')->info("foo") and automatically get
    $c passed in? I think I could have sth like:

    package MyApp::Model::Log;
    use base 'Catalyst::Model';

    my $last_c;

    sub ACCEPT_CONTEXT {
    my ($self, $c) = @_;
    $last_c = $c;
    }

    sub info {
    my ($self, $msg) = @_
    my $c = $last_c;
    ...
    }

    but this seems pretty messy...

    Mark
    Very very *VERY* bad idea.

    __PACKAGE__->mk_accessors(context);

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);
    return $new;
    }


    Something like the above instead.

    Ash
  • Mark Zealey at Dec 27, 2006 at 4:12 pm

    On Wednesday 27 December 2006 1:01 pm, Ash Berlin wrote:
    Very very *VERY* bad idea.

    __PACKAGE__->mk_accessors(context);

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);
    return $new;
    }
    Isn't that really really slow though? Constructing a new object for each call?
  • Jonathan Rockway at Dec 27, 2006 at 8:14 pm
    Isn't that really really slow though? Constructing a new object for each call?
    No, it's not. Creating an object in Perl amounts to setting a flag (the
    OBJECT flag in subclasses of SvPVMG, to be exact).

    See illguts: http://gisle.aas.no/perl/illguts/

    --
    package JAPH;use Catalyst qw/-Debug/;($;=JAPH)->config(name => do {
    $,.=reverse qw[Jonathan tsu rehton lre rekca Rockway][$_].[split //,
    ";$;"]->[$_].q; ;for 1..4;$,=~s;^.;;;$,});$;->setup;
  • Aristotle Pagaltzis at Dec 28, 2006 at 2:31 am

    * Jonathan Rockway [2006-12-27 21:25]:
    No, it's not. Creating an object in Perl amounts to setting a
    flag (the OBJECT flag in subclasses of SvPVMG, to be exact).

    See illguts: http://gisle.aas.no/perl/illguts/
    Are you being too literal on purpose? Yeah blessing a ref is just
    setting a flag but you need a referee for that ref and people
    don?t consider its creation a separate step in general.


    * Mark Zealey [2006-12-27 17:20]:
    On Wednesday 27 December 2006 1:01 pm, Ash Berlin wrote:
    Very very *VERY* bad idea.

    __PACKAGE__->mk_accessors(context);

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);
    return $new;
    }
    Isn't that really really slow though? Constructing a new object
    for each call?
    Well, it depends. If you call `$c->Model('Log')` a ton of times,
    then it will indeed be slow. If you don?t, you won?t notice.

    If you?ve *determined* from profiling that `$c->Model('Log')` is
    called enough to be a bottleneck, you have two options. The
    trivial one is that to store the object returned in a variable
    and then make your logging calls on that variable, so you don?t
    go through `ACCEPT_CONTEXT` constantly. The other is to memoise
    `ACCEPT_CONTEXT` so when it?s passed the same `$c`, it always
    returns the same copy. You?ll have to be very careful about your
    cache though; it?s easy to introduce leaks. If Catalyst depends
    critically on object destruction timing, you might even break the
    whole thing alltogether.

    In summary: avoid caring too much without specific reason to.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • Daniel McBrearty at Dec 29, 2006 at 7:47 pm
    FWIW ... : what I've noticed about using models (or not) ... :

    1. the advantage of using a model mostly seems to be that it
    autoloads, and then is accessible everywhere from $c. Otherwise, there
    doesn't seem to be much difference from just having a normal perl
    library.

    2. so if you just need data/logic for use in one controller, a
    standard library may be better.

    3. usually, I'm finding its better to try to keep the models as pure
    data sources, and not have them interact, or be context dependent. So
    I try to make it the controllers job to do anything that involves
    context, or to connect different models together where necessary. That
    seems to result in a cleaner API. I have started writing modules that
    took $c as an argument, but generally took it out later.

    4. of course there are exceptions ... which is why a framework that
    has flexibility and power is worth investing time to learn, even if it
    takes longer than one that says "we do it this way around here ..."

    this is just ideas that I've seen starting to emerge from many
    learner's mistakes ... others will know different / better ...

    On 12/28/06, A. Pagaltzis wrote:
    * Jonathan Rockway [2006-12-27 21:25]:
    No, it's not. Creating an object in Perl amounts to setting a
    flag (the OBJECT flag in subclasses of SvPVMG, to be exact).

    See illguts: http://gisle.aas.no/perl/illguts/
    Are you being too literal on purpose? Yeah blessing a ref is just
    setting a flag but you need a referee for that ref and people
    don't consider its creation a separate step in general.


    * Mark Zealey [2006-12-27 17:20]:
    On Wednesday 27 December 2006 1:01 pm, Ash Berlin wrote:
    Very very *VERY* bad idea.

    __PACKAGE__->mk_accessors(context);

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);
    return $new;
    }
    Isn't that really really slow though? Constructing a new object
    for each call?
    Well, it depends. If you call `$c->Model('Log')` a ton of times,
    then it will indeed be slow. If you don't, you won't notice.

    If you've *determined* from profiling that `$c->Model('Log')` is
    called enough to be a bottleneck, you have two options. The
    trivial one is that to store the object returned in a variable
    and then make your logging calls on that variable, so you don't
    go through `ACCEPT_CONTEXT` constantly. The other is to memoise
    `ACCEPT_CONTEXT` so when it's passed the same `$c`, it always
    returns the same copy. You'll have to be very careful about your
    cache though; it's easy to introduce leaks. If Catalyst depends
    critically on object destruction timing, you might even break the
    whole thing alltogether.

    In summary: avoid caring too much without specific reason to.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Christopher H. Laco at Dec 29, 2006 at 7:56 pm

    Daniel McBrearty wrote:
    FWIW ... : what I've noticed about using models (or not) ... :

    1. the advantage of using a model mostly seems to be that it
    autoloads, and then is accessible everywhere from $c. Otherwise, there
    doesn't seem to be much difference from just having a normal perl
    library.

    2. so if you just need data/logic for use in one controller, a
    standard library may be better.
    I generally agree, with one more note. A model that can have different
    settings for itself inside of Catalyst than it does as a standard module
    outside of Catalyst.

    Even then [for me], my Models are usual just glue between Cat specific
    settings and the non-Cat perl library.

    -=Chris

    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: signature.asc
    Type: application/pgp-signature
    Size: 189 bytes
    Desc: OpenPGP digital signature
    Url : http://lists.scsys.co.uk/pipermail/catalyst/attachments/20061229/16a61ba3/signature.pgp
  • Juan Miguel Paredes at Jan 31, 2007 at 3:23 pm

    On 12/27/06, Ash Berlin wrote:
    Mark Zealey wrote:
    Hi there,

    I'm basically wanting to write a simple log function which logs hits on my
    website as entries in a database (automatically adding $c->user->{id} and
    $c->req->referrer etc), but to do so I want to use a model (I think). Any
    ideas how I can just say $c->model('Log')->info("foo") and automatically get
    $c passed in? I think I could have sth like:

    package MyApp::Model::Log;
    use base 'Catalyst::Model';

    my $last_c;

    sub ACCEPT_CONTEXT {
    my ($self, $c) = @_;
    $last_c = $c;
    }

    sub info {
    my ($self, $msg) = @_
    my $c = $last_c;
    ...
    }

    but this seems pretty messy...

    Mark
    Very very *VERY* bad idea.

    __PACKAGE__->mk_accessors(context);

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);
    return $new;
    }


    Something like the above instead.

    Ash
    Hi, all!

    What if we have to overload ACCEPT_CONTEXT to do something like this,
    but using DBIC::Schema? What would be the recommended inheritance
    chain? Catalyst::Model::DBIC::Schema acts as a glue between the actual
    Catalyst model and the Schema classes, so I'm a little confused about
    where to start... In this particular case, we'd like to access $c
    from model in order to overload subroutines (trigger-like) to track,
    for example, which user modified what...

    Thanks in advance,

    Juan.
  • Matt S Trout at Jan 31, 2007 at 3:51 pm

    On 31 Jan 2007, at 15:23, Juan Miguel Paredes wrote:
    On 12/27/06, Ash Berlin wrote:
    Mark Zealey wrote:
    Hi there,

    I'm basically wanting to write a simple log function which logs
    hits on my
    website as entries in a database (automatically adding $c->user-> {id} and
    $c->req->referrer etc), but to do so I want to use a model (I
    think). Any
    ideas how I can just say $c->model('Log')->info("foo") and
    automatically get
    $c passed in? I think I could have sth like:

    package MyApp::Model::Log;
    use base 'Catalyst::Model';

    my $last_c;

    sub ACCEPT_CONTEXT {
    my ($self, $c) = @_;
    $last_c = $c;
    }

    sub info {
    my ($self, $msg) = @_
    my $c = $last_c;
    ...
    }

    but this seems pretty messy...

    Mark
    Very very *VERY* bad idea.

    __PACKAGE__->mk_accessors(context);

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);
    return $new;
    }


    Something like the above instead.

    Ash
    Hi, all!

    What if we have to overload ACCEPT_CONTEXT to do something like this,
    but using DBIC::Schema? What would be the recommended inheritance
    chain? Catalyst::Model::DBIC::Schema acts as a glue between the actual
    Catalyst model and the Schema classes, so I'm a little confused about
    where to start... In this particular case, we'd like to access $c
    from model in order to overload subroutines (trigger-like) to track,
    for example, which user modified what...
    add an accessor to the schema, and do $schema->clone then hand that
    $c->user

    --
    Matt S Trout, Technical Director, Shadowcat Systems Ltd.
    Offering custom development, consultancy and support contracts for
    Catalyst,
    DBIx::Class and BAST. Contact mst (at) shadowcatsystems.co.uk for
    details.
    + Help us build a better perl ORM: http://dbix-
    class.shadowcatsystems.co.uk/ +
  • Juan Miguel Paredes at Jan 31, 2007 at 7:27 pm

    On 1/31/07, Matt S Trout wrote:
    On 31 Jan 2007, at 15:23, Juan Miguel Paredes wrote:

    Hi, all!

    What if we have to overload ACCEPT_CONTEXT to do something like this,
    but using DBIC::Schema? What would be the recommended inheritance
    chain? Catalyst::Model::DBIC::Schema acts as a glue between the actual
    Catalyst model and the Schema classes, so I'm a little confused about
    where to start... In this particular case, we'd like to access $c
    from model in order to overload subroutines (trigger-like) to track,
    for example, which user modified what...
    add an accessor to the schema, and do $schema->clone then hand that
    $c->user
    Ok! I understand that ACCEPT_CONTEXT would have to be placed in a
    package along the Catalyst::Base inheritance chain, so, a feasible
    place would be in MyApp::Model::Schema (based on
    Catalyst::Model::DBIC::Schema). I've tried this:


    package MyApp::Model::BD;

    use strict;
    use base 'Catalyst::Model::DBIC::Schema';

    __PACKAGE__->mk_accessors( 'context' );

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);

    return $new;
    }

    In fact, placing some $c->log->debug in ACCEPT_CONTEXT shows it runs
    ok. The question is, if this is the right place to overload
    ACCEPT_CONTEXT, how would I access the context from, say:

    package MyApp::Schema::BD::TpRol;

    use strict;
    use base qw/DBIx::Class/;

    #table, add_columns, etc.

    sub update {
    my $self = shift;

    my $c = $self->context; # wrong, no method "context", because $self
    is a DBIx::Class::Row

    my $c = MyApp::Model::BD->context; # wrong, complains that Can't use
    string ("MyApp::Model::BD") as a HASH ref while "strict refs"

    return $self->next::method( @_ );
    }


    So, if the location for overloading ACCEPT_CONTEXT seems reasonable,
    accessing it from overloaded subroutines in ResultSource would be the
    last part of the puzzle. In this case, just as a proof of concept,
    I'm trying to access the whole $c, but later that could be refined
    with accessors for, say, just $c->user, $c->request->params, etc.

    Thanks again!

    Juan
  • Victor Igumnov at Feb 1, 2007 at 12:27 am
    To see the impact of the memory leak.

    Run broken.pl first which will run formbuilder against your installed
    version.
    It will create a new formbuilder instance over and over, watch top -o
    size as it grows to 100-200 megs in just a few seconds.

    Now run fixed.pl - works great don't it? No memory leaks what so ever.

    I have also included a CatTest catalyst project which uses
    C::C::FormBuilder. With everything patched up the process stays at
    ~14 megs while being hammered by ab -n 900 -c 100 http://localhost:
    3000/.

    So the question is am I the only one using formbuilder? This leak was
    very obvious.

    All tests pass for both projects.

    http://temp.fabulously40.com/~victori/CGI-FormBuilder-3.05-memfix.tbz

    -victor

    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070131/7b0816a3/attachment-0001.htm
  • Juan Camacho at Feb 1, 2007 at 4:37 am

    On 1/31/07, Victor Igumnov wrote:

    To see the impact of the memory leak.


    Run broken.pl first which will run formbuilder against your installed version.
    It will create a new formbuilder instance over and over, watch top -o size as it grows to 100-200 megs in just a few seconds.


    Now run fixed.pl - works great don't it? No memory leaks what so ever.


    I have also included a CatTest catalyst project which uses C::C::FormBuilder. With everything patched up the process stays at ~14 megs while being hammered by ab -n 900 -c 100 http://localhost:3000/.


    So the question is am I the only one using formbuilder? This leak was very obvious.


    All tests pass for both projects.


    http://temp.fabulously40.com/~victori/CGI-FormBuilder-3.05-memfix.tbz


    -victor
    Thank you Victor for pointing out the memory leak. I've attached your
    diff files here to make it easier on folks.

    After looking at it, I think your patch is just a workaround for the
    circular references in CGI::FormBuilder and fixing these problems
    directly instead of cloning references is a better approach. I have
    submitted a bug report to Nate at
    http://rt.cpan.org/Ticket/Display.html?id=24696 and he has already
    said he would look into it.

    Juan
    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: memfix-for-c-c-formbuilder.diff
    Type: application/octet-stream
    Size: 721 bytes
    Desc: not available
    Url : http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070131/149dc0f9/memfix-for-c-c-formbuilder.obj
    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: memleakfix-for-cgi-formbuilder.diff
    Type: application/octet-stream
    Size: 1343 bytes
    Desc: not available
    Url : http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070131/149dc0f9/memleakfix-for-cgi-formbuilder.obj
  • Victor Igumnov at Feb 1, 2007 at 8:03 pm
    The way its setup with so many circular references I could not figure
    out a way to weaken it correctly for the GC to let it go. Cloning
    seems to work well. It might not be the *best* fix but it works well.
    Concerning C::C::Formbuilder, I ran into a few issues so disregard
    my patch. At this point I am thinking of sticking formbuilder into
    the model and using it for data verification and exporting forms.
    Seems like double work when your controller has to verify data and
    then the model.

    -Victor

    On Jan 31, 2007, at 8:37 PM, Juan Camacho wrote:
    On 1/31/07, Victor Igumnov wrote:


    To see the impact of the memory leak.


    Run broken.pl first which will run formbuilder against your
    installed version.
    It will create a new formbuilder instance over and over, watch top
    -o size as it grows to 100-200 megs in just a few seconds.


    Now run fixed.pl - works great don't it? No memory leaks what so
    ever.


    I have also included a CatTest catalyst project which uses
    C::C::FormBuilder. With everything patched up the process stays at
    ~14 megs while being hammered by ab -n 900 -c 100 http://localhost:
    3000/.


    So the question is am I the only one using formbuilder? This leak
    was very obvious.


    All tests pass for both projects.


    http://temp.fabulously40.com/~victori/CGI-FormBuilder-3.05-memfix.tbz


    -victor
    Thank you Victor for pointing out the memory leak. I've attached your
    diff files here to make it easier on folks.

    After looking at it, I think your patch is just a workaround for the
    circular references in CGI::FormBuilder and fixing these problems
    directly instead of cloning references is a better approach. I have
    submitted a bug report to Nate at
    http://rt.cpan.org/Ticket/Display.html?id$696 and he has already
    said he would look into it.

    Juan
    <memfix-for-c-c-formbuilder.diff>
    <memleakfix-for-cgi-formbuilder.diff>
    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive: http://www.mail-archive.com/
    catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/
  • Matt S Trout at Feb 1, 2007 at 9:35 am

    On 31 Jan 2007, at 19:27, Juan Miguel Paredes wrote:
    On 1/31/07, Matt S Trout wrote:
    On 31 Jan 2007, at 15:23, Juan Miguel Paredes wrote:

    Hi, all!

    What if we have to overload ACCEPT_CONTEXT to do something like this,
    but using DBIC::Schema? What would be the recommended inheritance
    chain? Catalyst::Model::DBIC::Schema acts as a glue between the actual
    Catalyst model and the Schema classes, so I'm a little confused about
    where to start... In this particular case, we'd like to access $c
    from model in order to overload subroutines (trigger-like) to track,
    for example, which user modified what...
    add an accessor to the schema, and do $schema->clone then hand that
    $c->user
    Ok! I understand that ACCEPT_CONTEXT would have to be placed in a
    package along the Catalyst::Base inheritance chain, so, a feasible
    place would be in MyApp::Model::Schema (based on
    Catalyst::Model::DBIC::Schema). I've tried this:


    package MyApp::Model::BD;

    use strict;
    use base 'Catalyst::Model::DBIC::Schema';

    __PACKAGE__->mk_accessors( 'context' );

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->context($c);

    return $new;
    }
    package MyApp::DataStore; # or whatever this is called

    use base qw/DBIx::Class::Schema/;

    __PACKAGE__->mk_group_accessors(simple => 'context');

    then

    my $new = bless ...

    $new->schema(bless(...)); # same trick on the schema

    $new->schema->context($c);

    then in the DBIC code

    $self->result_source->schema->context;

    make more sense?

    --
    Matt S Trout, Technical Director, Shadowcat Systems Ltd.
    Offering custom development, consultancy and support contracts for
    Catalyst,
    DBIx::Class and BAST. Contact mst (at) shadowcatsystems.co.uk for
    details.
    + Help us build a better perl ORM: http://dbix-
    class.shadowcatsystems.co.uk/ +
  • Juan Miguel Paredes at Feb 1, 2007 at 3:30 pm

    On 2/1/07, Matt S Trout wrote:
    package MyApp::DataStore; # or whatever this is called

    use base qw/DBIx::Class::Schema/;

    __PACKAGE__->mk_group_accessors(simple => 'context');

    then

    my $new = bless ...

    $new->schema(bless(...)); # same trick on the schema

    $new->schema->context($c);

    then in the DBIC code

    $self->result_source->schema->context;

    make more sense?
    Indeed, your suggestion worked fine, thanks a lot! Just had to add
    DBIx::Class::AccessorGroup to the schema class

    Regards,

    Juan.
  • Scott Thomson at Feb 27, 2007 at 11:25 am
    Hi,

    This is exactly what I want to do, however I can't seem to get my head round
    how to implement this solution, I've tried various incarnations but I don't
    seem to be getting anywhere.

    Annotations below, thanks for patience.

    Scott

    On 2/1/07, Juan Miguel Paredes wrote:
    On 2/1/07, Matt S Trout wrote:

    package MyApp::DataStore; # or whatever this is called

    use base qw/DBIx::Class::Schema/;

    __PACKAGE__->mk_group_accessors(simple => 'context');


    I get this bit, (also add DBIx::Class::AccessorGroup to the base class list)

    then
    my $new = bless ...
    $new->schema(bless(...)); # same trick on the schema

    $new->schema->context($c);

    Is the above in the same file? what should replace the ellipsis
    then in the DBIC code
    $self->result_source->schema->context;

    make more sense?

    Where exactly is the DBIC code? MyApp::Model::DataStore?

    Indeed, your suggestion worked fine, thanks a lot! Just had to add
    DBIx::Class::AccessorGroup to the schema class

    Regards,

    Juan.

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070227/573e00e1/attachment.htm
  • Scott Thomson at Mar 5, 2007 at 12:02 pm
    Ok, I think I'm close...

    My main schema class:

    package DB;

    use base qw/DBIx::Class::Schema DBIx::Class::AccessorGroup/;

    __PACKAGE__->mk_group_accessors(simple => 'context');
    __PACKAGE__->load_classes(qw//);
    1;


    My model class...

    package WCN::Model::DB;

    use strict;
    use base qw/Catalyst::Model::DBIC::Schema::WCN/;

    __PACKAGE__->config(
    schema_class => 'DB',
    );

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    $c->log->debug(" *** class: " . ref($self));

    my $new = bless({%$self}, ref $self);
    $new->schema(bless({%{$self->schema}}, ref($self->schema)));
    $new->schema->context($c);

    # Outputs 'WCN' which is correct
    $c->log->debug(" *** ref of context in self: ",
    ref($new->schema->context()));

    return $new;
    }

    The debug prints the correct class of $c when ACCEPT_CONTEXT is
    called, however $self->result_source->schema->context is not present
    in the model objects.

    Have I got the wrong end of the stick somewhere?

    Many Thanks,

    Scott.

    On 2/27/07, Scott Thomson wrote:
    Hi,

    This is exactly what I want to do, however I can't seem to get my head round
    how to implement this solution, I've tried various incarnations but I don't
    seem to be getting anywhere.

    Annotations below, thanks for patience.

    Scott

    On 2/1/07, Juan Miguel Paredes wrote:
    On 2/1/07, Matt S Trout wrote:

    package MyApp::DataStore; # or whatever this is called

    use base qw/DBIx::Class::Schema/;

    __PACKAGE__->mk_group_accessors(simple => 'context');


    I get this bit, (also add DBIx::Class::AccessorGroup to the base class list)
    then

    my $new = bless ...
    $new->schema(bless(...)); # same trick on the schema

    $new->schema->context($c);
    Is the above in the same file? what should replace the ellipsis
    then in the DBIC code

    $self->result_source->schema->context;

    make more sense?

    Where exactly is the DBIC code? MyApp::Model::DataStore?

    Indeed, your suggestion worked fine, thanks a lot! Just had to add
    DBIx::Class::AccessorGroup to the schema class

    Regards,

    Juan.

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo:
    http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/
  • Juan Miguel Paredes at Mar 5, 2007 at 9:52 pm

    On 3/5/07, Scott Thomson wrote:
    Ok, I think I'm close...

    My main schema class:

    package DB;

    use base qw/DBIx::Class::Schema DBIx::Class::AccessorGroup/;

    __PACKAGE__->mk_group_accessors(simple => 'context');
    __PACKAGE__->load_classes(qw//);
    1;


    My model class...

    package WCN::Model::DB;

    use strict;
    use base qw/Catalyst::Model::DBIC::Schema::WCN/;

    __PACKAGE__->config(
    schema_class => 'DB',
    );

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    $c->log->debug(" *** class: " . ref($self));

    my $new = bless({%$self}, ref $self);
    $new->schema(bless({%{$self->schema}}, ref($self->schema)));
    $new->schema->context($c);

    # Outputs 'WCN' which is correct
    $c->log->debug(" *** ref of context in self: ",
    ref($new->schema->context()));

    return $new;
    }

    The debug prints the correct class of $c when ACCEPT_CONTEXT is
    called, however $self->result_source->schema->context is not present
    in the model objects.

    Have I got the wrong end of the stick somewhere?

    Many Thanks,

    Scott.
    That looks very similar to what we did, but in the model class:

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->schema->_context($c);
    return $new;
    }

    (we used _context for accesor)

    Also, I don't know if the DB namespace is reserved for debug, and
    could lead to complications... I think I read that in a nearby thread
    a while ago, but can't locate it right now...

    Regards,
    Juan.
  • Scott Thomson at Mar 6, 2007 at 8:43 am
    Excellent, that works - Thank you!
    On 3/5/07, Juan Miguel Paredes wrote:
    On 3/5/07, Scott Thomson wrote:
    Ok, I think I'm close...

    My main schema class:

    package DB;

    use base qw/DBIx::Class::Schema DBIx::Class::AccessorGroup/;

    __PACKAGE__->mk_group_accessors(simple => 'context');
    __PACKAGE__->load_classes(qw//);
    1;


    My model class...

    package WCN::Model::DB;

    use strict;
    use base qw/Catalyst::Model::DBIC::Schema::WCN/;

    __PACKAGE__->config(
    schema_class => 'DB',
    );

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    $c->log->debug(" *** class: " . ref($self));

    my $new = bless({%$self}, ref $self);
    $new->schema(bless({%{$self->schema}}, ref($self->schema)));
    $new->schema->context($c);

    # Outputs 'WCN' which is correct
    $c->log->debug(" *** ref of context in self: ",
    ref($new->schema->context()));

    return $new;
    }

    The debug prints the correct class of $c when ACCEPT_CONTEXT is
    called, however $self->result_source->schema->context is not present
    in the model objects.

    Have I got the wrong end of the stick somewhere?

    Many Thanks,

    Scott.
    That looks very similar to what we did, but in the model class:

    sub ACCEPT_CONTEXT {
    my ($self, $c, @args) = @_;

    my $new = bless({ %$self }, ref $self);
    $new->schema->_context($c);
    return $new;
    }

    (we used _context for accesor)

    Also, I don't know if the DB namespace is reserved for debug, and
    could lead to complications... I think I read that in a nearby thread
    a while ago, but can't locate it right now...

    Regards,
    Juan.

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/
  • Jason Kohles at Mar 6, 2007 at 7:51 pm

    On Mar 5, 2007, at 7:02 AM, Scott Thomson wrote:

    Ok, I think I'm close...

    My main schema class:

    package DB;

    use base qw/DBIx::Class::Schema DBIx::Class::AccessorGroup/;

    __PACKAGE__->mk_group_accessors(simple => 'context');
    __PACKAGE__->load_classes(qw//);
    1;
    Very Bad Things are likely to happen if you ever attempt to run your
    application under the debugger when you have a package named 'DB'.
    I'd recommend using a different name...

    --
    Jason Kohles
    email@jasonkohles.com
    http://www.jasonkohles.com/
    "A witty saying proves nothing." -- Voltaire


    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070306/adb65b20/attachment.htm
  • Scott Thomson at Mar 6, 2007 at 8:28 pm
    Noted and actioned, Cheers.

    Very Bad Things are likely to happen if you ever attempt to run your
    application under the debugger when you have a package named 'DB'. I'd
    recommend using a different name...

    --
    Jason Kohles
    email@jasonkohles.com
    http://www.jasonkohles.com/
    "A witty saying proves nothing." -- Voltaire



    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070306/2359d116/attachment.htm
  • Eden Cardim at Dec 27, 2006 at 4:32 pm

    On 12/27/06, Mark Zealey wrote:
    Hi there,

    I'm basically wanting to write a simple log function which logs hits on my
    website as entries in a database (automatically adding $c->user->{id} and
    $c->req->referrer etc), but to do so I want to use a model (I think). Any
    ideas how I can just say $c->model('Log')->info("foo") and automatically get
    $c passed in?
    What's wrong with $c->forward('Model::Log', 'info', ['foo']) ?

    --
    Eden Cardim
    Instituto Baiano de Biotecnologia
    N?cleo de Biologia Computacional e Gest?o de Informa??es Biotecnol?gicas
    Laborat?rio de Bioinform?tica
    --
    "you seem to think that 'close enough' is close enough...
    please learn to be 'literal' around programming."
    merlyn - on irc.freenode.net#perl
  • John Napiorkowski at Dec 27, 2006 at 8:54 pm

    --- Eden Cardim wrote:
    On 12/27/06, Mark Zealey wrote:
    Hi there,

    I'm basically wanting to write a simple log
    function which logs hits on my
    website as entries in a database (automatically
    adding $c->user->{id} and
    $c->req->referrer etc), but to do so I want to use
    a model (I think). Any
    ideas how I can just say
    $c->model('Log')->info("foo") and automatically get
    $c passed in?
    What's wrong with $c->forward('Model::Log', 'info',
    ['foo']) ?
    This discussion is bring back old nightmares for me :)
    Catalyst is really flexible but I personally haven't
    really figured out the value of:

    ## Forward style
    $c->forward('Model::Log', 'info', ['foo'])

    versus

    ## direct invocation style
    $c->model('Log')->info("foo") with/without using
    ACCEPT_CONTEXT to have this instantiate a new object
    for each request

    versus

    ## Classic Perl style
    Use Model::Log;

    my $log = Model::Log->new(...);
    $log->info($c,'foo');

    I tend to use forwarding mostly for controllers,
    although with Chaining I find I need this less and
    less. I also use forward to delegate to a view
    handler.
    From what I can see the main advantage of forward is
    that it sends the context for you automatically. Also
    you get the automatic return but this to me seems less
    important with a model and more relevant to
    controllers. Usually my models return self or some
    sort of value anyway.

    The only advantage I can see for making your business
    objects into catalyst models is that you get the handy
    config methods that you can centralize in your main
    configuration file if you like. And it saves you
    having to add 'use ...' at the top of all the
    controllers that need a particular model (although you
    can create a base controller to help with this issue).

    I'm certainly offtopic by now but this question gets
    asked of me by my coworkers and I wish I had more than
    a list of pro/cons to give as an answer.

    --john
    --
    Eden Cardim
    Instituto Baiano de Biotecnologia
    N?cleo de Biologia Computacional e Gest?o de
    Informa??es Biotecnol?gicas
    Laborat?rio de Bioinform?tica
    --
    "you seem to think that 'close enough' is close
    enough...
    please learn to be 'literal' around programming."
    merlyn - on irc.freenode.net#perl

    _______________________________________________
    List: Catalyst@lists.rawmode.org
    Listinfo:
    http://lists.rawmode.org/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.rawmode.org/
    Dev site: http://dev.catalyst.perl.org/

    __________________________________________________
    Do You Yahoo!?
    Tired of spam? Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com

Related Discussions

People

Translate

site design / logo © 2021 Grokbase