List Info

Thread: The model -is- where your business logic lives.




The model -is- where your business logic lives.
country flaguser name
United States
2007-09-27 05:51:26
In a previous thread, Matt S Trout said.

>The model -is- where your business logic lives.
>
>The real question is whether your ORM should be directly
in the model or
>not, but that's a whole different thread.

Based on this I have the following simple code.

####
package MyApp::Model:BIC;

use strict;
use base qw(Catalyst::Model:BIC::Sch
ema);

####
package MyApp::Schema:emo;

use base qw(DBIx::Class);

__PACKAGE__->load_components(qw(PK::Auto Core));
__PACKAGE__->table('demo');
__PACKAGE__->add_columns(qw(id name state));
__PACKAGE__->set_primary_key('id');


####
package MyApp::Model:BIC:emo;

sub do_some_business_logic_stuff {
    my ($self) = _;

    if (<some complicated business logic>) {
        $self->state('pending');
        $self->update;
    }
}   


#### somewhere in my application

$demo = $c->model('DBIC:emo')-&g
t;find($index);
$demo->do_some_business_logic_stuff;

-------------

Is this a standard/typical/best-practice way to do this sort
of thing? 

It seems to me that if I want to use the business logic in
an external application (cronjob) then I am having to use
the MyApp::Model:BIC:emo
namespace as decreed by Catalyst (not that this is a big
issue).

Regards
Ian



_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

Re: The model -is- where your business logic lives.
user name
2007-09-27 06:16:49
Hi,

On Sep 27, 2007, at 11:51 AM, Ian Docherty wrote:

> In a previous thread, Matt S Trout said.
>
>> The model -is- where your business logic lives.
>>
>> The real question is whether your ORM should be
directly in the  
>> model or
>> not, but that's a whole different thread.
>
> Based on this I have the following simple code.
>
[....]
>
> Is this a standard/typical/best-practice way to do this
sort of thing?

That's what I do with two minor adjustements:

  * I started using load_namespaces to control each source
resultset  
class also;
  * I don't put my model inside the catalyst application.

> It seems to me that if I want to use the business logic
in an  
> external application (cronjob) then I am having to use
the  
> MyApp::Model:BIC:emo
namespace as decreed by Catalyst (not that  
> this is a big issue).

se 2) above. Most of the time I have Demo::Controller,
Demo::Model,  
Demo::View, and my schema is Demo::Schema.

So I can use Demo::Schema in all my crons.

See the SYNOPSIS of http://search.cpan.or
g/perldoc? 
Catalyst::Model:BIC::Sch
ema on how to do it.

Best regards,
-- 
Pedro Melo
Blog: http://www.simplic
idade.org/notes/
XMPP ID: melosimplicidade.org
Use XMPP!



_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

Re: The model -is- where your business logic lives.
country flaguser name
United States
2007-09-27 07:05:55
Pedro Melo wrote:
[...]
That's what I do with two minor adjustements:

 * I started using load_namespaces to control each source resultset class also;
 * I don't put my model inside the catalyst application.

It seems to me that if I want to use the business logic in an external application (cronjob) then I am having to use the MyApp::Model:BIC:emo namespace as decreed by Catalyst (not that this is a big issue).

se 2) above. Most of the time I have Demo::Controller, Demo::Model, Demo::View, and my schema is Demo::Schema.

So I can use Demo::Schema in all my crons.
(I assume you mean MyApp::Controller, MyApp::Model etc?)

So, if I read the documentation correctly, I would then have my resultsets in MyApp::Schema::ResultSet:emo and my results in MyApp::Schema::Result:emo?

I don't see how this helps me with the namespace in Catalyst, if I use $c-&gt;model('DBIC:emo') won't it still come back with the namespace MyApp::Model:BIC:emo?

Can you show an example of your call to load_namespaces?

See the SYNOPSIS of http://search.cpan.org/perldoc?Catalyst::Model:BIC::Schema on how to do it.

Best regards,

Regards
Ian


Re: The model -is- where your business logic lives.
country flaguser name
United States
2007-09-27 07:14:08
Pedro Melo wrote:
>
> That's what I do with two minor adjustements:
>
>  * I started using load_namespaces to control each
source resultset 
> class also;
>  * I don't put my model inside the catalyst
application.
>
And is load_namespaces significantly slower than using
load_classes with 
all classes explicitly specified?

Regards
Ian


_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

Re: The model -is- where your business logic lives.
country flaguser name
United Kingdom
2007-09-27 15:43:44
On Thu, Sep 27, 2007 at 11:51:26AM +0100, Ian Docherty
wrote:
> In a previous thread, Matt S Trout said.
> 
> >The model -is- where your business logic lives.
> >
> >The real question is whether your ORM should be
directly in the model or
> >not, but that's a whole different thread.
> 
> Based on this I have the following simple code.
> 
> ####
> package MyApp::Model:BIC;
> 
> use strict;
> use base qw(Catalyst::Model:BIC::Sch
ema);
> 
> ####
> package MyApp::Schema:emo;
> 
> use base qw(DBIx::Class);
> 
> __PACKAGE__->load_components(qw(PK::Auto Core));
> __PACKAGE__->table('demo');
> __PACKAGE__->add_columns(qw(id name state));
> __PACKAGE__->set_primary_key('id');
> 
> 
> ####
> package MyApp::Model:BIC:emo;

Put this code in MyApp::Schema:emo.

I often call it e.g. MyApp:ataStore
or MyApp:omain to
remind me that
it's the business layer and the DBIC-ness is merely
incidental.
 
> sub do_some_business_logic_stuff {
>    my ($self) = _;
> 
>    if (<some complicated business logic>) {
>        $self->state('pending');
>        $self->update;
>    }
> }   
> 
> 
> #### somewhere in my application
> 
> $demo = $c->model('DBIC:emo')-&g
t;find($index);
> $demo->do_some_business_logic_stuff;
> 
> -------------
> 
> Is this a standard/typical/best-practice way to do this
sort of thing? 
> 
> It seems to me that if I want to use the business logic
in an external 
> application (cronjob) then I am having to use the
MyApp::Model:BIC:emo 
> namespace as decreed by Catalyst (not that this is a
big issue).

Having moved the logic out of MyApp::Model:: this ceases to
be an issue.

Don't confuse class -names- with the nature of classes.
MyApp::Model:: is
*adapters* that make a model available to MyApp, not where
your domain model
logic itself should live.

I usually these days have MyApp::Web for the catalyst app
instead of MyApp so
I can deploy things like MyApp:ataStore
from a separate dir tree.

-- 
      Matt S Trout       Need help with your Catalyst or
DBIx::Class project?
   Technical Director                    http://www.shado
wcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or
deployment platform?
http://chainsawblues.vo
x.com/            http://www.shadow
cat.co.uk/servers/

_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

RE: The model -is- where your business logic lives.
user name
2007-09-28 02:22:01
 

>-----Message d'origine-----
>De : Matt S Trout [mailto:dbix-classtrout.me.uk] 
>Envoyé : jeudi, 27. septembre 2007 22:44

>Don't confuse class -names- with the nature of classes.

>MyApp::Model:: is
>*adapters* that make a model available to MyApp, not
where 
>your domain model
>logic itself should live.
>
>I usually these days have MyApp::Web for the catalyst
app 
>instead of MyApp so
>I can deploy things like MyApp:ataStore
from a separate dir tree.


Makes a lot of sense to me. So the model can be used not
only from the catalyst App, but also from batch jobs,
command-line utilities, etc. And the Catalyst model
*adapters*, as you call them, merely load the appropriate
external modules, that's all.

But then comes a question about writing Catalyst code :
which is best between a) and b) below ?

# a) go through the adapter for every method call
$c->model('Some::Model::Adapter')->do_stuff()  

# b) directly call the external model after it's loaded
My::External::Model->do_stuff()                 


I tend to prefer b) because the code dealing with business
logic always looks the same, either within the Catalyst app
or within the command-line utilities. And if there is some
global state in the external model (like sharing the DB
connection, or setting/changing properties on that
connection), it makes it very clear to every client that
they are interacting with the same common global state.
Finally, it saves a couple of method calls.

My colleague prefers a) because it's the usual,
"oficial" Catalyst way, and because if we ever
need some reverse interaction from the model to the
controller, we can add stuff in the adapters, playing with
ACCEPT_CONTEXT.

Any other opinions in this debate ?

Best regards, L. Dami

_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

Re: The model -is- where your business logic lives.
country flaguser name
United States
2007-09-28 02:55:09
Matt S Trout wrote:
jules.scsys.co.uk" type="cite">
Put this code in MyApp::Schema:emo.

I often call it e.g. MyApp:ataStore or MyApp:omain to remind me that
it's the business layer and the DBIC-ness is merely incidental.
 
  
sub do_some_business_logic_stuff {
   my ($self) = _;

   if (<some complicated business logic>) {
       $self->state('pending');
       $self->update;
   }
}   


#### somewhere in my application

$demo = $c->model('DBIC:emo')->find($index);
$demo-&gt;do_some_business_logic_stuff;


-------------

Is this a standard/typical/best-practice way to do this sort of thing? 

It seems to me that if I want to use the business logic in an external 
application (cronjob) then I am having to use the MyApp::Model:BIC:emo 
namespace as decreed by Catalyst (not that this is a big issue).
    

Having moved the logic out of MyApp::Model:: this ceases to be an issue.

Don't confuse class -names- with the nature of classes. MyApp::Model:: is
*adapters* that make a model available to MyApp, not where your domain model
logic itself should live.

I usually these days have MyApp::Web for the catalyst app instead of MyApp so
I can deploy things like MyApp:ataStore from a separate dir tree.
  
Yes I did briefly have that confusion, but I think I am mostly straight with it now and I (largely) have the layout you suggest. Just to confirm I currently have the following

MyCompany::MyApp::Controller
MyCompany::MyApp::View
MyCompany::MyApp::Model
MyCompany::MyApp::Schema (where my ORM goes)
MyCompany::MyApp::Logic (where my other business logic goes)

I originally created the 'Logic' namespace because I was using load_classes and by default my Schema directory had all my ORM result_source files.

However I am just in the process of changing to using load_namespaces so I now have

MyCompany::MyApp::Schema::Result (where I have moved all my result_sources to)
MyCompany::MyApp::Schema::ResultSet

leaving  MyCompany::MyApp::Schema empty of classes.

So I presume I can consider the MyCompany::MyApp::Schema namespace to be for my business logic that does not directly map onto a ORM? (I can't think of a good example off-hand.)

One final point that I am not sure I have right.

In my business logic I have certain constraints (for example the maximum length of a web-form field, e.g. username) and most of the time this constraint is defined by the database (the field length of the user.username). Now the template needs access to these values to display the appropriate error message so typically I do the following in my controller.

$c-&gt;stash-&gt;{constraints} = MyCompany::MyApp::Schema::Result::User-&gt;constraints;

with the following in my User ORM

my $constraints =  {
   ; usernamename => {
   ; &nbsp; &nbsp; min_length  ; &nbsp;  => 0,
 ; &nbsp; &nbsp; &nbsp; max_length  ; &nbsp;  => 15,
&nbsp; &nbsp; },
# etc.
};

sub constraints {
   ; my ($self) = _;
 ; &nbsp; return $constraints;
}

Which leaves me feeling a little ill-at-ease since it seems wrong to me to have a class method to do this but I don't understand why!

Regards
Ian


Re: The model -is- where your business logic lives.
user name
2007-09-28 04:51:17
Hi,

On Sep 28, 2007, at 8:22 AM, Dami Laurent (PJ) wrote:

>
>
>> -----Message d'origine-----
>> De : Matt S Trout [mailto:dbix-classtrout.me.uk]
>> Envoyé : jeudi, 27. septembre 2007 22:44
>
>> Don't confuse class -names- with the nature of
classes.
>> MyApp::Model:: is
>> *adapters* that make a model available to MyApp,
not where
>> your domain model
>> logic itself should live.
>>
>> I usually these days have MyApp::Web for the
catalyst app
>> instead of MyApp so
>> I can deploy things like MyApp:ataStore
from a separate dir tree.
>
>
> Makes a lot of sense to me. So the model can be used
not only from  
> the catalyst App, but also from batch jobs,
command-line utilities,  
> etc. And the Catalyst model *adapters*, as you call
them, merely  
> load the appropriate external modules, that's all.
>
> But then comes a question about writing Catalyst code :
which is  
> best between a) and b) below ?
>
> # a) go through the adapter for every method call
> $c->model('Some::Model::Adapter')->do_stuff()
>
> # b) directly call the external model after it's
loaded
> My::External::Model->do_stuff()

b) here exactly for the same reasons: i like having the same
API when  
I'm using Cat or not.

Besides, most of my projects have two sites (frontoffice,
backoffice)  
so I prefer to have the connection details outside the
catalyst sites.

I never did use $c->model in my sites...

> My colleague prefers a) because it's the usual,
"oficial" Catalyst  
> way, and because if we ever need some reverse
interaction from the  
> model to the controller, we can add stuff in the
adapters, playing  
> with ACCEPT_CONTEXT.

Callbacks work for me when I need to do this.

Best regards,
-- 
Pedro Melo
Blog: http://www.simplic
idade.org/notes/
XMPP ID: melosimplicidade.org
Use XMPP!



_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

Re: The model -is- where your business logic lives.
user name
2007-09-28 04:58:20
Hi,

On Sep 28, 2007, at 8:55 AM, Ian Docherty wrote:

> MyCompany::MyApp::Controller
> MyCompany::MyApp::View
> MyCompany::MyApp::Model
> MyCompany::MyApp::Schema (where my ORM goes)
> MyCompany::MyApp::Logic (where my other business logic
goes)
>
> I originally created the 'Logic' namespace because I
was using  
> load_classes and by default my Schema directory had all
my ORM  
> result_source files.
>
> However I am just in the process of changing to using 

> load_namespaces so I now have
>
> MyCompany::MyApp::Schema::Result (where I have moved
all my  
> result_sources to)
> MyCompany::MyApp::Schema::ResultSet

I travelled the same path: I started with split Logic and
Schema  
classes and move them all together with load_namespaces. It
works  
fine, and thats the approach I recommend around here.

> leaving  MyCompany::MyApp::Schema empty of classes.
>
> So I presume I can consider the
MyCompany::MyApp::Schema namespace  
> to be for my business logic that does not directly map
onto a ORM?  
> (I can't think of a good example off-hand.)

I would defer that decision until you get a good example


> One final point that I am not sure I have right.
>
> In my business logic I have certain constraints (for
example the  
> maximum length of a web-form field, e.g. username) and
most of the  
> time this constraint is defined by the database (the
field length  
> of the user.username). Now the template needs access to
these  
> values to display the appropriate error message so
typically I do  
> the following in my controller.

You have attributes in the add_columns() to store all that.
And if  
you do store them all in there, you can use  
DBIx::Class::Schema::deploy as a added bonus.

See:

  * deploy: http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/

Schema.pm#deploy
  * add_columns: http
://search.cpan.org/dist/DBIx-Class/lib/DBIx/ 
Class/ResultSource.pm#add_columns

Best regards,
-- 
Pedro Melo
Blog: http://www.simplic
idade.org/notes/
XMPP ID: melosimplicidade.org
Use XMPP!



_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

Re: The model -is- where your business logic lives.
user name
2007-09-28 11:01:43
On 9/27/07, Matt S Trout <dbix-classtrout.me.uk> wrote:
>
> I usually these days have MyApp::Web for the catalyst
app instead of MyApp so
> I can deploy things like MyApp:ataStore
from a separate dir tree.
>

How do you deal with configuring the database connection for
things
like cron jobs outside of catalyst?  Do you have the
connection info
in the DataStore module?  Locating the config file from any
one of
several applications or crons that might use it seems
tricky, and I
don't want to have that information in the config files of
several
apps, but maybe that makes sense since some of them might
eventually
only talk to a read-only slave.

-- 
Barry Hoggard

_______________________________________________
List: Catalystlists.rawmode.org
Listinfo: ht
tp://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-
archive.com/catalystlists.rawmode.org/
Dev site: http://dev.catalyst.per
l.org/

[1-10]

about | contact  Other archives ( Real Estate discussion Medical topics )