[Catalyst] Simple literal Model

Octavian Rasnita orasnita at gmail.com
Sat Feb 26 08:07:55 GMT 2011


From: "John M. Dlugosz" <wxju46gefd at 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




More information about the Catalyst mailing list