Alen
Alen

Reputation: 3

Kohana Fragment cache and results from database

I'm trying to optimize my Kohana (3.2.2) aplication with the Fragment helper class and just realized that I'm doing it wrong.

Model_Article:

    public function get_articles()
    {
        /*
         * This is just a PDO wrapper, I don't like the kohana built in
         * database module
         */
        $db = DB::instance();

        $article_stmt = $db->prepare("SELECT * FROM articles");
        $article_stmt->execute();
        return $article_stmt->fetchAll();
    }


Controller_Article:

    public function action_index()
    {
        $this->template->content = View::factory('welcome/index');

        $this->template->content->articles = Model::factory('article')->get_articles();
    }


The view:

        <?php if ( ! Fragment::load('home.articles')): ?>

            <!-- cache test -->

            <?php foreach($articles as $article) echo $article->title . PHP_EOL ?>

            <?php Fragment::save(); ?>
        <?php endif; ?>


You can see, the query is always executed, no matter what's going on in the view. I want the query to be executed just when the cache gets updated. But passing the model object to the view would break some MVC convetions I guess?! Can someone show me how to do it right?!

Upvotes: 0

Views: 791

Answers (2)

Giovanne Afonso
Giovanne Afonso

Reputation: 706

You must do the query in the View (If you extends Controller_Template) or echo in the controller (If you extends Controller).

Examples

Controller_Article (extends Controller):

public function action_index()
{
    if ( ! Fragment::load('home.articles')):

        $template = View::factory('my_template_view');

        $template->content = View::factory('welcome/index');
        $template->content->articles = Model::factory('article')->get_articles();

        echo $template->render();   // If you won't print anything,
                                    // don't use fragments

        Fragment::save();   // Save the OUTPUT, but DOES NOT save variables
    endif;
}

 

Controller_article (extends Controller_Template):

public function action_index()
{
    $this->template->content = View::factory('welcome/index');
}

View (welcome/index):

<?php
    // echo $articles;     // Now Controller is not binding this variable
    if ( ! Fragment::load('home.articles')):

        // Variable - Does NOT save in Fragment
        $articles = Model::factory('article')->get_articles();

        // ECHO = save to Fragment
        foreach($articles as $article) echo $article->title . PHP_EOL;

        Fragment::save();   // Save the OUTPUT, but DOES NOT save variables
    endif;
?>

 

If you want to save variables, use Kohana Cache.

Upvotes: 0

Chvanikoff
Chvanikoff

Reputation: 1329

Cache handling is what the controller should do, not view.

Move it from view to controller and be happy. I didn't use Fragment module but I guess you will understand the main point:

public function action_index()
{
    $this->template->content = View::factory('welcome/index');
    if ( ! $articles = Fragment::load('home.articles') )
    {
        // It's better to use separate view for articles list
        $articles = View::factory('articles/list', array('articles' => Model::factory('article')->get_articles());
        // Hope not just an output can be captured but argument can also be passed to the save() method of the module
        Fragment::save($articles);
    }
    $this->template->content->articles = $articles;
}

Upvotes: 1

Related Questions