Search code examples
phpormfat-free-framework

Fat Free Framework - Loading array of data from a query


I have no issues loading a unique record from my DB utilizing F3's ORM. However, when I want to retrieve multiple records for display or processing, the load method will still only fetch the first it finds.

I've found this on the docs:

By default, a data mapper's load() method retrieves only the first record that matches the specified criteria. If you have more than one that meets the same condition as the first record loaded, you can use the skip() method for navigation

However the docs then continue only to show how to manipulate multiple records with built in find method, which returns an object filled with references to database entries.

I prefer not to loop through multiple records every time, I think there must be something I'm missing, how does one do this with fat free? In the docs it even references code where you can just do the following after a simply DB call, but I've yet to see how to do that with provided methods:

<repeat group="{{ @result }}" value="{{ @item }}">
    <span>{{ @item.brandName  }}</span>
</repeat>

What is the proper way to obtain a batch of records? For an example, please see below:

$productList = $products->load(array('created_on >= ?', $date->timestamp)); //Load most recently created products

or

$productList = $products->find(array('created_on >= ?',$date->timestamp),array('order'=>'created_on'));

In the example above, the date is utilizing Carbon, assume that is a proper timestamp.


Solution

  • I don't think there is a proper way to retrieve a bunch of records. The SQL mapper acts as a cursor. The best way to see how it works is with the load method: the mapper will retrieve all matching records and set its focus on the first one. You can do what you want with it and then call next to move on to the next one:

    $products->load(array('created_on >= ?', $date->timestamp));
    while (!$products->dry() ) {
        // Do something with the record
        $products->next();
    }
    

    The find method will return an array of records (actually they are also cursors, but each has only one record so you can treat them just as objects which are mapped to the records). Here, you will need to assign the result to a new variable like you did in your example:

    $productList = $products->find(array('created_on >= ?',$date->timestamp),array('order'=>'created_on'));
    // You can loop over the array to get some info or update the records:
    foreach ($productList as $product) {
        // Do something with the record
    }
    

    Or you can directly use the $productList variable in the template:

    <repeat group="{{ @productList }}" value="{{ @item }}">
        <span>{{ @item.brandName  }}</span>
    </repeat>