FAQ
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?

Search Discussions

  • Tomas Doran at Feb 25, 2011 at 10:04 am

    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
  • John M. Dlugosz at Feb 25, 2011 at 10:27 am

    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
  • Ashley Pond V at Feb 25, 2011 at 3:30 pm

    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
  • John M. Dlugosz at Feb 26, 2011 at 5:22 am

    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
  • Octavian Rasnita at Feb 26, 2011 at 8:07 am
    From: "John M. Dlugosz" <wxju46gefd@snkmail.com>
    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
  • Ashley Pond V at Feb 26, 2011 at 5:11 pm

    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.
  • Zbigniew Lukasiak at Mar 1, 2011 at 1:23 pm

    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.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedFeb 25, '11 at 1:56a
activeMar 1, '11 at 1:23p
posts8
users5
websitecatalystframework.org
irc#catalyst

People

Translate

site design / logo © 2021 Grokbase