Ivan
Ivan

Reputation: 5248

Codeigniter call other controller in view

How to merge two controllers in one view.

I have two controllers:

1. PostController

2. CommentController

Post controller will show all posts from database, and that posts can have comments. For comments i use another controller CommentController to avoid DRY. In html post list while looping am trying to attach comments if exist for all post bassed on their ID.

In my PostController > indexAction() am fetch all posts

// controllers/PostController.php
/**
 * List all posts
 *
 */
public function index()
{
    $data = array(
        'posts' => $this->post->findAll(),
    );

    $this->load->view('post/index', $data);
}

Here is method from comment controller for listing comments assigning post_id:

// controllers/CommentController.php

/**
 * List all comments assigning post id 
 *
 * @param int $post_id
 */
public function index($post_id)
{
    $data = array(
        'comments' => $this->comment->findAllByPostId($post_id), // <-- SELECT * FROM comments WHERE post_id = {post_id}
    );

    $this->load->view('comment/index', $data);
}

So now in post/index am fetch all posts:

<?php if($posts): ?>
<?php foreach ($posts as $post): ?>
    <h1> <?= $post->title; ?> </h1>
    <div> <?= $post->text; ?> </div>

    <div class="comment-list"> 
       <!-- How to call here comment controller and index($post->post_id) -->
       <!-- i can use load->view('comment/index') but with this i do nothin i need to assigning  post id

       <!-- Need somthing $commentObject->index($post->post_id) but this in MVC is not good idea --> 
    </div>

<?php endforeach() ;?>
<?php endif; ?>

Any other solution ?

My solution to slove this is to put all in one controller Post. But i think that is bad practice bcs i will DRY latter. I need that comment controller for other ex(PictureController can have also comments i dont want DRY)

Maybe my process or organization is bad ?

ps. i to search SO for this but that results not helpful for me

Upvotes: 1

Views: 1220

Answers (2)

cartalot
cartalot

Reputation: 3148

the controller gets the data from a model. so in general any database interaction is going to happen in the model, and then that controller asks "did you get my information? if yes, show it, if no, do something else" When everything is sorted out the data is sent to the view.

one controller can call from many different models, and can send more then one data structure to the view.

    public function index()
    {
            // assuming you have a model called 'post'
            // check if any posts came back from the search
            if( ! $posts  = $this->post->findAll() )
            { 
                $this->_showNoPostsReturned() ; 
            } 

            // now assuming you have a model called comment 
            // in your model you will have to foreach through posts etc

           // did any comments come back? 
           elseif( ! $comments = $this->comment->returnFor($posts) )
           {
               $this->_showOnlyThe($posts) ; 
           } 
           // else we have posts and comments 
           else{ $this->_showBoth($posts,$comments) ; }

  }

  private function _showBoth($posts,$comments){

   // this is how you pass more then one data structure 
   // array, object, text, etc etc 
   // with $data['name']

   $data['posts'] =  $posts ; 
   $data['comments'] =  $comments ; 

   // and call more then one view if necessary 
   $this->load->view('post/index', $data);
   $this->load->view('comment/index', $data);

   } 

so this index method is only asking for data from models, and then depending on what if any data it gets back - it calls a separate private method and that method can call the appropriate views. In other words now you don't need to do this in your view

<?php if($posts): ?>

thats what you want to avoid, because then the view is making decisions about what to show. obviously some logic is going to happen in views, but as much as possible all decisions should happen in the controller.

Upvotes: 1

ArSeN
ArSeN

Reputation: 5248

Meta

First of all, I think you do actually want to DRY, as DRY means "Don't Repeat Yourself". I think you got the concept but reading that you "don't want to DRY" is kind of confusing ;)

Answer

Secondly: In a classical MVC approach (which CodeIgniter really much does), one does indeed let the controller handle the model that is then (or data from it) passed on to the view.

Now there are different concepts on how to retrieve all data that you want from the controller, e.g. really reading all of it out in a controller and then passing it on the the view, as compared to only passing the "post" models and let the view take out the posts comments in the view itself. I think both have valid reasons and you can decide which one to use (and there are others, too!), even though I prefer the latter one.

One alternative could be to use a "Decorator Pattern" (see Wikipedia), which seems to have an userland implementation in CodeIgniter only: https://github.com/ccschmitz/codeigniter-decorator

TL;DR

Your approach is imho fine, but you might look into decorator patterns (see above).

Upvotes: 0

Related Questions