Re: [Catalyst] Simple literal Model
On Sat, Feb 26, 2011 at 6:22 AM, John M. Dlugosz wrote: > On 2/25/2011 9:30 AM, Ashley Pond V apv-at-sedition.com |Catalyst/Allow > to home| wrote: > >> What t0m suggested is perfectly fine but if you want to mimic the DBIC >> API with a different engine, this example does that (superficially and >> as a tutorial only): http://sedition.com/a/2739 Log file model–Apache >> access log. The reason that example makes sense is because the >> underlying model/data is similar: searchable, sortable rows. If you're >> trying to shoehorn in something dissimilar, you might be making a >> mistake. >> >> -Ashley >> > I'm not sure to what extent it is wise or correct. > The whole point of "models" is that it abstracts the model and I can change > where the data comes from later, right? So don't they all have an > underlying abstract interface regardless of how they are sourced? > The only abstraction Catalyst::Model provides is initialization. Personally I don't like this approach but I cannot imagine what common abstraction it could provide for so diverse models. Some Catalyst::Model::xxx classes do provide some additional functionality - like Catalyst::Model::DBIC which adds the possibility to address the resutlsets with a shortcut - but it's their own unique additions. -- Zbigniew Lukasiak http://brudnopis.blogspot.com/ http://perlalchemy.blogspot.com/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Simple literal Model
On Fri, Feb 25, 2011 at 9:22 PM, John M. Dlugosz wrote: > On 2/25/2011 9:30 AM, Ashley Pond V apv-at-sedition.com |Catalyst/Allow to > home| wrote: >> >> What t0m suggested is perfectly fine but if you want to mimic the DBIC >> API with a different engine, this example does that (superficially and >> as a tutorial only): http://sedition.com/a/2739 Log file model–Apache >> access log. The reason that example makes sense is because the >> underlying model/data is similar: searchable, sortable rows. If you're >> trying to shoehorn in something dissimilar, you might be making a >> mistake. >> >> -Ashley > > I'm not sure to what extent it is wise or correct. > The whole point of "models" is that it abstracts the model and I can change > where the data comes from later, right? So don't they all have an > underlying abstract interface regardless of how they are sourced? Well, models just differ. DOM, relational, even hash and array with all their similarity need some minor acrobatics if they are to be treated alike. You can make an API to attempt to unify all the possible data models but that would create an artificial complexity much harder to track and work with. This hits a sore spot for me. I've seen what I take to be a sort of "purity of MVC" just about kill projects and make them incredibly painful to work on. The layers are to make work easier, testable, quicker, delegated, etc, not to achieve some fantasy where the templates from a Cat app can be plugged into Rails or Django without modification. > The examples I've read using DBIC use > [% WHILE ( item = list.next) %] > and I can imagine that in general we don't have efficient random access to > the rows; in C++ I would characterize this as a "forward iterator" or even > weaker, if I can't make a copy of the earlier state and go forward a second > time. > > I would have hoped that the TT [% FOREACH %] directive would work here. > That seems like the natural means of abstracting the list. That is, the > controller can set anything into the stash that FOREACH knows how to handle, > including a plain Perl array. The API for that in DBIC+TT would look like [% FOR record IN list.all() %] or list.search({contraints...},{rows=>max_rows}) or list.search_related() etc, etc. The idioms are mostly the same in TT as plain Perl. "for" can't recursively call an iterator any more than "while" can unroll a list. ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Simple literal Model
From: "John M. Dlugosz" > On 2/25/2011 9:30 AM, Ashley Pond V apv-at-sedition.com |Catalyst/Allow to > home| wrote: >> What t0m suggested is perfectly fine but if you want to mimic the DBIC >> API with a different engine, this example does that (superficially and >> as a tutorial only): http://sedition.com/a/2739 Log file model–Apache >> access log. The reason that example makes sense is because the >> underlying model/data is similar: searchable, sortable rows. If you're >> trying to shoehorn in something dissimilar, you might be making a >> mistake. >> >> -Ashley > I'm not sure to what extent it is wise or correct. > The whole point of "models" is that it abstracts the model and I can change > where the data > comes from later, right? So don't they all have an underlying abstract > interface > regardless of how they are sourced? > I can see that DBIC itself abstracts which database is used; e.g. SQL Lite > for testing and > MySQL on a dedicated server for deployment. But I was thinking that the > Model, over all, > did a similar level of abstraction: change from a database to a XML file or > other > representation, and the data is still presented the same way. > > For example, I currently have 8 items, and want to just list them in Perl so > I don't have > to worry about another data representation or parsing it. But if needs to > become > user-changable or grows to a few dozen items, a separate XML file would be > better. And if > it grows to a search result of a few thousand items, it should be in a > database. > > Clearly there are differences in capabilities of a Model: to wit, "all in" > or > "searchable". And a full database can return different results depending on > selected > columns, across joins, etc. So I think the level of abstraction is that of > "a list of > records". The View is given a list of records, and the Controller knows to > pull it by > name directly, perform a search on a more complex model, or access an > attribute of a more > encompassing model. It obtains the list and passes it to the View via the > stash. > > The examples I've read using DBIC use > [% WHILE ( item = list.next) %] > and I can imagine that in general we don't have efficient random access to > the rows; in > C++ I would characterize this as a "forward iterator" or even weaker, if I > can't make a > copy of the earlier state and go forward a second time. > > I would have hoped that the TT [% FOREACH %] directive would work here. That > seems like > the natural means of abstracting the list. That is, the controller can set > anything into > the stash that FOREACH knows how to handle, including a plain Perl array. > > So, is it an oversight of the documentation examples or of the framework that > FOREACH > isn't used on the DBIC result set? > > --John The resultset is an iterator and you need to use the next() method for getting its items. If you want you can get a list of items from the resultset using the all() method, then you can use FOREACH to loop that list. The iterator is prefered for performance reasons but when using DBIC for displaying data in web pages, you probably don't need to display very large lists of elements, so you can use FOREACH with no problems. my @list = $rs->search(...)->all; foreach my $item ( @list ) { print $item->column_name; } If you call the search() function on a resultset in list context, the result will be a list of items and not a resultset, so you don't need to use the all() method: my @list = $rs->search(...); Octavian ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Simple literal Model
On 2/25/2011 9:30 AM, Ashley Pond V apv-at-sedition.com |Catalyst/Allow to home| wrote: What t0m suggested is perfectly fine but if you want to mimic the DBIC API with a different engine, this example does that (superficially and as a tutorial only): http://sedition.com/a/2739 Log file model–Apache access log. The reason that example makes sense is because the underlying model/data is similar: searchable, sortable rows. If you're trying to shoehorn in something dissimilar, you might be making a mistake. -Ashley I'm not sure to what extent it is wise or correct. The whole point of "models" is that it abstracts the model and I can change where the data comes from later, right? So don't they all have an underlying abstract interface regardless of how they are sourced? I can see that DBIC itself abstracts which database is used; e.g. SQL Lite for testing and MySQL on a dedicated server for deployment. But I was thinking that the Model, over all, did a similar level of abstraction: change from a database to a XML file or other representation, and the data is still presented the same way. For example, I currently have 8 items, and want to just list them in Perl so I don't have to worry about another data representation or parsing it. But if needs to become user-changable or grows to a few dozen items, a separate XML file would be better. And if it grows to a search result of a few thousand items, it should be in a database. Clearly there are differences in capabilities of a Model: to wit, "all in" or "searchable". And a full database can return different results depending on selected columns, across joins, etc. So I think the level of abstraction is that of "a list of records". The View is given a list of records, and the Controller knows to pull it by name directly, perform a search on a more complex model, or access an attribute of a more encompassing model. It obtains the list and passes it to the View via the stash. The examples I've read using DBIC use [% WHILE ( item = list.next) %] and I can imagine that in general we don't have efficient random access to the rows; in C++ I would characterize this as a "forward iterator" or even weaker, if I can't make a copy of the earlier state and go forward a second time. I would have hoped that the TT [% FOREACH %] directive would work here. That seems like the natural means of abstracting the list. That is, the controller can set anything into the stash that FOREACH knows how to handle, including a plain Perl array. So, is it an oversight of the documentation examples or of the framework that FOREACH isn't used on the DBIC result set? --John ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Simple literal Model
On Fri, Feb 25, 2011 at 2:27 AM, John M. Dlugosz wrote: > On 2/25/2011 4:06 AM, Tomas Doran bobtfish-at-bobtfish.net |Catalyst/Allow > to home| wrote: >> >> __PACKAGE__->meta->make_immutable; >> 1; >> >> And you then call $c->model('Foo')->data; >> >> The implementation of the 'data' method could then later be replaced by an >> attribute (i.e. has data => ( is => 'ro', isa => 'HashRef' );), and would >> then get the data from config, or something more complex (e.g. to get the >> data out of DBI, or another model, or whatever). >> >> HTH >> Cheers >> t0m >> > Thanks. Is '$c->model('Foo')->data' what something like DBIC gives us, too? > That is, is a method named 'data' the convention? That is, if code was > given a "result set" (I think that is the right term) of a query that was > made on one of the main standard model types, what would the list of records > look like? > What t0m suggested is perfectly fine but if you want to mimic the DBIC API with a different engine, this example does that (superficially and as a tutorial only): http://sedition.com/a/2739 Log file model–Apache access log. The reason that example makes sense is because the underlying model/data is similar: searchable, sortable rows. If you're trying to shoehorn in something dissimilar, you might be making a mistake. -Ashley ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Simple literal Model
On 2/25/2011 4:06 AM, Tomas Doran bobtfish-at-bobtfish.net |Catalyst/Allow to home| wrote: __PACKAGE__->meta->make_immutable; 1; And you then call $c->model('Foo')->data; The implementation of the 'data' method could then later be replaced by an attribute (i.e. has data => ( is => 'ro', isa => 'HashRef' );), and would then get the data from config, or something more complex (e.g. to get the data out of DBI, or another model, or whatever). HTH Cheers t0m Thanks. Is '$c->model('Foo')->data' what something like DBIC gives us, too? That is, is a method named 'data' the convention? That is, if code was given a "result set" (I think that is the right term) of a query that was made on one of the main standard model types, what would the list of records look like? Does 'MyApp_create.pl model' have any built-in stuff to generate a blank ad-hoc model like you showed me? Thanks for the help. --John ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Simple literal Model
On 25 Feb 2011, at 01:56, John M. Dlugosz wrote: I'm planning several web pages that will be the same except for the actual content. Rather than code the details in the TT template or prepare a list literally in the Controller, I'm thinking that this ought to go into a Model. But, it can just be a Perl declaration. Something like: my @data= ( { foo=>'bar', items=>[qw/first second third/], bar=>'baz }, # 7 more rows ); and add to that some subs to slice and dice the information so the TT doesn't have to; e.g. give a list of all the foo's. How do I create a "static, literal" Model? And, what would its form be in order to make it properly abstract, so it =could= be replaced with a standard DBIC or other model back- end without affecting the code? package MyApp::Model::Foo; use Moose; use Method::Signatures::Simple; use namespace::autoclean; extends 'Catalyst::Model'; method data { return { { foo=>'bar', items=>[qw/first second third/], bar=>'baz }, ... }; }; __PACKAGE__->meta->make_immutable; 1; And you then call $c->model('Foo')->data; The implementation of the 'data' method could then later be replaced by an attribute (i.e. has data => ( is => 'ro', isa => 'HashRef' );), and would then get the data from config, or something more complex (e.g. to get the data out of DBI, or another model, or whatever). HTH Cheers t0m ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Simple literal Model
I'm planning several web pages that will be the same except for the actual content. Rather than code the details in the TT template or prepare a list literally in the Controller, I'm thinking that this ought to go into a Model. But, it can just be a Perl declaration. Something like: my @data= ( { foo=>'bar', items=>[qw/first second third/], bar=>'baz }, # 7 more rows ); and add to that some subs to slice and dice the information so the TT doesn't have to; e.g. give a list of all the foo's. How do I create a "static, literal" Model? And, what would its form be in order to make it properly abstract, so it =could= be replaced with a standard DBIC or other model back-end without affecting the code? ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/