Welcome Guest, Not a member yet? Register   Sign In
If data exists in the field print, else don't
#11

[eluser]zebake[/eluser]
You guys have gotten me closer, but I'm still not quite there.

Error I am currently receiving:
Code:
A PHP Error was encountered

      Severity: Warning

      Message: Invalid argument supplied for foreach()

      Filename: views/student_directory_view.php

      Line Number: 8

I've looked over all the advice here and this is how I have modified everything:

Database
Code:
#
# Source for table parents
#

CREATE TABLE `parents` (
  `parent_id` int(11) NOT NULL auto_increment,
  `lname` varchar(255) default NULL,
  `fname` varchar(255) default NULL,
  `street` varchar(255) default NULL,
  `city` varchar(255) default NULL,
  `state` varchar(255) default NULL,
  `zip` varchar(255) default NULL,
  `email` varchar(255) default NULL,
  `phone` varchar(255) default NULL,
  `cell` varchar(255) default NULL,
  PRIMARY KEY  (`parent_id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

#
# Dumping data for table parents
#

INSERT INTO `parents` VALUES (1,'Smith','Farrah','123 Sesame St.','Dallas','TX','75217','[email protected]','555-555-5555','555-555-5555');
INSERT INTO `parents` VALUES (2,'Smith','Gus',NULL,NULL,NULL,NULL,NULL,NULL,'555-555-5555');
INSERT INTO `parents` VALUES (3,'Jones','Lyndsey','456 Main St.','Dallas','TX','75216','[email protected]','555-555-5555','555-555-5555');

#
# Source for table students
#

CREATE TABLE `students` (
  `student_id` int(11) NOT NULL auto_increment,
  `lname` varchar(255) default NULL,
  `fname` varchar(255) default NULL,
  PRIMARY KEY  (`student_id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

#
# Dumping data for table students
#

INSERT INTO `students` VALUES (1,'Smith','Abbey');
INSERT INTO `students` VALUES (2,'Smith','Jason');
INSERT INTO `students` VALUES (3,'Jones','Sarah');

#
# Source for table students_parents
#

CREATE TABLE `students_parents` (
  `student_id` int(11) NOT NULL default '0',
  `parent_id` int(11) NOT NULL default '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

#
# Dumping data for table students_parents
#

INSERT INTO `students_parents` VALUES (1,1);
INSERT INTO `students_parents` VALUES (1,2);
INSERT INTO `students_parents` VALUES (2,1);
INSERT INTO `students_parents` VALUES (2,2);
INSERT INTO `students_parents` VALUES (3,3);

I think I am using the students_parents table (students_guardians as you have it) correctly...I added a row to associate each student_id with their respective parent_id(s). Is this correct?

student_directory_model.php
Code:
<?php
class Student_directory_model extends Model {

    function Student_directory_model()
    {
        // Call the Model constructor
        parent::Model();
    }
    
    function get_all_students()
        {
            //Query the data table for ALL STUDENTS
            $query = $this->db->select('students.*, parents.fname, parents.lname')
                        ->join('students_parents', 'students_parents.student_id = students.student_id')
                        ->join('parents', 'students_parents.parent_id = parents.parent_id')
                        ->order_by('students.lname, students.fname')
                        ->get('students')->result_array();
        }
}
?>

student_directory_view.php

Code:
<html>  
<head>  
    <title><?=$page_title?></title>  
</head>  
<body>  
    <h1>&lt;?=$page_title?&gt;</h1>
    <ul>
        &lt;?php foreach($students as $student)
            {
                 echo $student['student_id'];
                 echo "<li>{$student['lname']}, {$student['fname']}</li>";
            }
        ?&gt;
    </ul>
&lt;/body&gt;  
&lt;/html&gt;

student_directory.php

Code:
&lt;?php
    class Student_directory extends Controller{
        function Student_directory()
        {
            parent::Controller();
            
            $this->load->scaffolding('students');
       }
        
        function index()
        {
            $this->load->model('student_directory_model');

            $data['students'] = $this->student_directory_model->get_all_students();
            $data['page_title'] = "SJES Student Directory";

            $this->load->view('student_directory_view',$data);
        }
    }
?&gt;

I hope I'm not butchering your advice too badly.
#12

[eluser]jedd[/eluser]
This one's easy.

Your model doesn't return anything.
#13

[eluser]jedd[/eluser]
Now .. I was in the middle of a lengthier response when that one turned up. I'll get back to it Wink

Fuzzy - you should flag this first post in your Helpful Links List - it's a pretty close-to-perfect question (in the sense of what was provided, not the specific problem).

Zebake - you probably want to read up a bit on [url="http://en.wikipedia.org/wiki/Database_normalisation"]database normalisation[/url]. It's a pretty dry subject, but designing your db right (or at least mostly right) at the beginning will save you a world of troubles later on. As you observed, the insight someone gave you above actually answered questions you knew you didn't have yet but soon would.

Whenever you find yourself writing something like address_alt or email_2 .. you know you're doing something wrong.

I'd actually blow out the number of tables even further. It sounds like it's making it more complex, but it's actually saving you complexity later. Also there's this natural resistance to multiple tables, where one or two 'should do the trick okay', when you're starting out - as you probably also expect there's a performance hit to be had. Generally there isn't. Databases are designed to do exactly the kind of thing we're talking about here - aggregating and cross-referencing multiple tables really really fast. If you're in doubt, set up a test bed and run up a million or so rows under each scenario and do some performance testing. Test data is cheap! (And very informative.)

Oh, anyway, yes, to turn that ramble into something specifically related to this problem. I'd have a separate table for email addresses, street addresses, possibly mobile/cell phones (but usually you just get (w), (m), (f), and (h) phone fields and be done with it for a given contact). Given the context I wouldn't bother with a zip_code table .. so no one can accuse me of going overboard.

results .v. result_array - I always use arrays, but I don't come from an OO background so this feels more natural. The facts are that they are usually smaller and consequently faster, and I very rarely have any need for OO features of returned database-row objects.

Oh, one final thing that might bite you later, when you start doing slightly more complex things, is the distinction between $this->data and $data - you're using the latter here, and it'll work just fine, but it tends to break when you rely on things being inserted into $this->data in other locations (typically MY_Controller - when you extend the base controller class). Have a read up on it, anyway, just so you know it's out there .. waiting for you.
#14

[eluser]TheFuzzy0ne[/eluser]
Jedd - any suggestions for a descriptive title? I briefly scanned a few of the posts, but I'm not quite sure how many other this could help, since it's a fairly unique question, is it not? Perhaps I'm missing something, (I usually am). My thread is for CodeIgniter Resources, not helpful links. Wink
#15

[eluser]jedd[/eluser]
Hmm, you're probably right. It will be better filed as an example under my yet-to-be-written 'How to ask a good question on the forums' wiki page. This is a good example as it ticked so many boxes - statement (and proof) of having RTFM'd, statement of desired intent and of actual output, and cleanly laid out code dump showing progress so far (rather than a plaintive 'please to be supplying me codes' style missive).

I suppose that by the time you've mentioned the CI Resources thread, it's usually to someone who's already missed the point.
#16

[eluser]slowgary[/eluser]
zebake,

I notice you're loading your model with a lower case 's', but it should be capitalized since your model is too. I would expect that to throw it's own error though, so maybe it's not the problem. Oh...I see it. Your model is assigning the query results to $query but not returning any of it. Get rid of the variable and just return it directly. So:
Code:
function get_all_students()
        {
            //Query the data table for ALL STUDENTS
            return $this->db->select('students.*, parents.fname, parents.lname')
                        ->join('students_parents', 'students_parents.student_id = students.student_id')
                        ->join('parents', 'students_parents.parent_id = parents.parent_id')
                        ->order_by('students.lname, students.fname')
                        ->get('students')->result_array();
        }

Usually the best way to troubleshoot your actual queries is to throw $this->output->enable_profiler(TRUE) into your controller and then copy and paste the query from your profiling data into something like phpMyAdmin.
#17

[eluser]jedd[/eluser]
[quote author="slowgary" date="1246562183"]Oh...I see it. Your model is assigning the query results to $query but not returning any of it.[/quote]

[url="http://ellislab.com/forums/viewreply/603760/"]I wish I'd noticed that.[/url] Wink

Quote:Get rid of the variable and just return it directly.

For the sake of completeness, you'd probably want to check that you had something to return - say with num_rows - and perhaps return FALSE if you did not. I know you can check this at the other end - in the controller or even pass it straight to the view and let it deal with it - but I think it's more elegant to do this in the model, and always pass back consistently formatted data.

By consistently-formatted, I mean never passing NULL'd variables around unintentionally.
#18

[eluser]slowgary[/eluser]
Makes sense. I'm still wondering why there was no error from attempting to load the model uncapitalized. I was under the impression it mattered, apparently not.

Jedd's model code:
Code:
function get_all_students()
        {
            //Query the data table for ALL STUDENTS
            $query = $this->db->select('students.*, parents.fname, parents.lname')
                        ->join('students_parents', 'students_parents.student_id = students.student_id')
                        ->join('parents', 'students_parents.parent_id = parents.parent_id')
                        ->order_by('students.lname, students.fname')
                        ->get('students');

            return ($query->num_rows() > 0)? $query->result_array() : FALSE;
        }
#19

[eluser]slowgary[/eluser]
Sorry Jedd, I just realized... you meant "does not have a return statement". I read it as "there aren't any results" or something, until I saw the lack of return statement, at which point I'd already forgotten about the contents of your first post.
#20

[eluser]jedd[/eluser]
It's all good in the hood.

If you'd called yourself fastgary I'd be ribbing you much less jovially Wink




Theme © iAndrew 2016 - Forum software by © MyBB