hehe.. you want layers, I got layers.. In addition to everything already mentioned I wanted to get Bread::Board in on the act..
I've put Lecstor up on GitHub if you're interested along with a Catalyst app that uses it. Neither really do much but boy is there a lot of scaffolding! ..and all the tests pass! 8) The basic hook-up is Catalyst -> Catalyst Models -> Bread::Board Containers -> Lecstor App/Models -> DBIC and others.. decoupled like a broken bag o marbles.. the Catalyst Models: - LecstorApp - application lifetime - LecstorModel - application lifetime - LecstorRequest - request lifetime - Lecstor - request lifetime LecstorModel & LecstorRequest return Bread::Board containers. LecstorApp returns a parameterized Bread::Board container Lecstor grabs the first two and shoves them into the third to make another Bread::Board container from which I get my app.. have I gone walkabout!? https://github.com/lecstor/Lecstor https://github.com/lecstor/Lecstor-Shop-Catalyst comments welcome. cheers, J On Tue, Jan 10, 2012 at 12:16 AM, Jason Galea <[email protected]>wrote: > > > On Mon, Jan 9, 2012 at 3:14 PM, Bill Moseley <[email protected]> wrote: > >> >> >> On Monday, January 2, 2012, Jason Galea wrote: >> >>> >>> I think I've added another layer but I'm not sure where you draw the >>> line.. I have a model layer over DBIC pulling together related result >>> classes under a single model class. Then the app? layer uses the model >>> layer to get things done. So I'd probably have one "distribution" that is >>> our DBIC wrapped in a model layer layer and use that in a number of apps.. >>> 8) Each app can then be used as the single model in a Catalyst app or >>> script or whatever.. (I think I need more names for the parts..) >>> >> >> Yes, where to draw the line is difficult to know. I've only had a few >> hours to work on this but already I feel like I'm reinventing Catalyst -- >> mostly because my model layer is pulling in much of the components that my >> Catalyst app would normally do -- DBIC, caching, even some concept of the >> "current user". Access control is another topic. >> > > The problem parts for me are DBIC and TT. I thought I could just set up > the components as usual, then load my app with them but it get's tricky > calling one component from another at setup time, although it all works > fine if you instantiate the app per request. So now I'm connecting/creating > those myself. > > For other things provided by plugins I'm working more with Catalyst so for > caching I will probably have my app accept a cache object at construction > and pass in the Catalyst cache. For Authentication I've created my own > store and user for the Catalyst Authentication plugin and they use my app > to do what they have to. I've also created a store for the session plugin > which uses my app, so all-in-all my app can see/touch everything that > Catalyst is doing, and I can still make use of all the Catalyst stuff > available (hopefully). > > >> >>> I have "Sets" in lu of ResultSets and "Models" for Results. Although in >>> most instances a Model will actually cover the usage of multiple Results. >>> Each Set gets the dbic schema object and knows it's resultset name. Each >>> model has a data attribute which contains a dbic row object and "handles" >>> any methods I don't need to override via the Moose "handles" attribute >>> attribute!? >>> >>> Set->create($hash) creates the dbic object and stuffs it into a model >>> class and returns that. >>> >> >> So you are mirroring DBICs class structure a bit. I need to consider >> that approach more as currently my model layer returns the DBIC row object >> directly. So, I have something like this: >> >> my $user_model = Model::User->new; >> my $new_user = $user->new_user( $user_data ); >> > >> Not as flexible as your approach but my goal currently is to just >> abstract out the ORM so that Model::User can hide the specifics of the >> database. Actually, it's not that hard to do directly with DBIC, either. >> > > yeh, I decided a while back that DBIx::Class is complicated enough and I'm > too lazy to keep trying to work out complicated solutions in the DBIC > classes to do things I know I can do quickly and easily with regular Moose > classes.. and I like having nice clean DBIC classes.. > > >> >> >>> Each result class that has a model class overrides it's inflate_result >>> method which again stuffs the dbic row object into the model object so >>> searches on the related dbic resultsets return my model objects. >>> >> >> Can you show a code example of that? I'm not sure I'm following why you >> use that approach instead of having your layer on top of DBIC do that. >> > > and the exception to the rule.. I did have my Set classes (which I now > refer to as Model Controllers) grabbing search results and looping through, > inflating them all into my Model Instances but then I couldn't just grab a > resultset if I needed to limit/restrict/whatever, and any search or find > had to be put through that ringer. With inflate_result I know that no > matter how I get the results they'll be instances of my model. create is > the only thing that doesn't work for so my controller does the wrapping > there. > > package Lecstor::Schema::Result::Person; > use base qw/DBIx::Class/; > __PACKAGE__->load_components(qw/ Core /); > __PACKAGE__->table('person'); > __PACKAGE__->add_columns('id' ,'firstname','surname'); > __PACKAGE__->set_primary_key('id'); > > sub inflate_result { > my $self = shift; > my $ret = $self->next::method(@_); > return unless $ret; > return Lecstor::Model::Instance::Person->new( _record => $ret ); > } > > 1; > > >> >>> >>> Each model class has a validation class based on.. Validation::Class and >>> create & update run their input through that. If there are errors I stuff >>> the errors into a very basic exception object and return that. This way I >>> can return the same exception object no matter where the error comes from, >>> eg a dbic exception.. >>> >> >> Yes, I'm doing something very similar where validation happens before the >> method in the model and on validation errors and exception is thrown (if >> you are on the Moose list you may have seen my example). >> >> Thanks for the feedback and the ideas, >> > > no worries at all, happy to be able to provide it. > > cheers, > > J > > >> >> >> >> -- >> Bill Moseley >> [email protected] >> >> _______________________________________________ >> List: [email protected] >> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst >> Searchable archive: >> http://www.mail-archive.com/[email protected]/ >> Dev site: http://dev.catalyst.perl.org/ >> >> >
_______________________________________________ List: [email protected] Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/[email protected]/ Dev site: http://dev.catalyst.perl.org/
