1

This is a situation I have found myself in a few times and I just want clear it up once and for all.

Best just to show you what I need to do in some example code.

My Controller

function my_controller()
{

$id = $this->uri->segment(3);

$this->db->from('cue_sheets');
$this->db->where('id', $id);
$data['get_cue_sheets'] = $this->db->get();

$this->db->from('clips');
$this->db->where('sheet_id', ' CUE SHEET ID GOES IN HERE ??? ');
$data['get_clips'] = $this->db->get();

$this->load->view('show_sheets_and_clips', $data);

}

My View

<?php if($get_cue_sheets->result_array()) { ?>
    <?php foreach($get_cue_sheets->result_array() as $sheetRow): ?>
        <h1><?php echo $sheetRow['sheet_name']; ?></h1>
        <br/>
        <?php if($get_clips->result_array()) { ?>
            <ul>
                <?php foreach($get_clips->result_array() as $clipRow): ?>
                    <li><?php echo $clipRow['clip_name']; ?></li>
                <?php endforeach; ?>
            </ul>
        <?php } else { echo 'No Clips Found'; } ?>
    <?php endforeach; ?>
<?php } ?>

So basically I am trying to display a number of sheets and then within each of those sheets the clips that belong to that sheet.

I hope this makes sense to someone out there.

Thanks,

Tim

Tim
  • 3,091
  • 9
  • 48
  • 64

4 Answers4

8

A user on the Code Igniter Forums came up with the solution below. The original thread is here.

It’s not efficient to look up the clips for every sheet separately. Use a JOIN query to get both lists at the same time.

// get the data
$this->db->from('cue_sheets');
$this->db->where('cue_sheets.id', $id);
$this->db->join('clips', 'clips.sheet_id = cue_sheets.id', 'left');
$rawdata = $this->db->get()->result_array();
// prepare the data into a multidimensional array
$data = array();
foreach($rawdata as $row)
{
  // if this is the first clip of a new sheet, make a new entry for it
  if (!isset($data[$row['id']]))
  {
    $data[$row['id']] = $row;
    $data[$row['id']]['clips'] = array();
  }  

  // add the current clip to the sheet
  $data[$row['id']]['clips'][] = $row;
}

Now in your view you can loop through the sheets, and within that, loop through the clips:

foreach($data as $sheet) {
  // make header etc.
  if (sizeof($sheet['clips']))
  {
    foreach($sheet['clips'] as $clip)
    {
      // show clip
    }
  } else {
    // show 'no clips'
  }
} 

Thanks again,

Tim

Tim
  • 3,091
  • 9
  • 48
  • 64
1

You should do a join in your model for both tables, and create one result which you will move later to your view trough the controller.

Remember not to put queries in your controller.

maybe somthing like this:

function get_data($cue_sheets){
$this->db->select(clips.*);
$this->db->from('clips');
$this->db->join('cue_sheets', 'clips.idcuesheet = cue_sheets.idcuesheet' );
$this->db->where('cue_sheets.idcuesheet', $cue_sheets);
$query = $this->db->get();
}

Or something similar.

Then you bring it to the controller

$data['clips'] = $this->clips->get_data($cue_sheets);

and finally to your view

foreach($clips as $clip){
echo $clip->clip_name;
}

Hope it helps

  • Thanks for posting that. I am a little confused as to why you said not to put queries in your controllers. I am aware that the MVC approach says that all DB access be done through models, however thankfully codeigniter is modular enough to allow database queries from within controllers. This is how I have been developing the rest of my app and I would be interested to hear why I should be avoiding this practice. Thanks – Tim Jun 16 '10 at 00:50
  • I can think of 3 reasons right now: 1) Simplicitym, with this your controller will be much easear to read and debugg. 2) It will be much easiear to change the database stuff 3) reusable, your code is much reusable this way, if you need info about a clip in your case in another controller you dont need to re-write the method, you just make a call to your model. – Gerardo Jaramillo Jun 16 '10 at 05:09
0

As far as I know, there's not really a way to pass data back to the controller from the view. I myself have not ever felt the need to. Your controller should be gathering the data and then passing it to the view. If you have additional data to get from your database results, do that first and then pass it to your view along with the original data.

Maybe I'm not understanding your question though...

Matthew
  • 15,282
  • 27
  • 88
  • 123
0

I'm not fully certain I understand you, but I think you want to get all "clips" from all "sheets" given by the first db call. Perhaps following might work:

$this->db->from('clips');
$this->db->where_in('sheet_id', array_map( function($sheet) { return $sheet['id'] }, $data['get_cue_sheets']->result_array() ) );
$data['get_clips'] = $this->db->get();
azatoth
  • 2,379
  • 15
  • 18
  • Interesting. Unfortunately I am getting the following error when I implement your solution. Parse error: syntax error, unexpected T_FUNCTION, expecting ')' – Tim Jun 15 '10 at 02:20