• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
If data exists in the field print, else don't

#1
[eluser]zebake[/eluser]
Hello, new to CI and have limited php experience. I am attempting to write a student directory database application for my son's school. I have watched the tutorials and read up on the user guide. I have setup a mysql database and thanks to the video tutorials, I am able to retrieve and display the information fine. The problem I have run into is the occasional situation where a child may have two separate households (divorced parents). In this event, I need to print the information for both households. I have setup the database with the extra / alternate fields and populated them with info. How do I print the alternate contact info only if it exists, and not print anything otherwise?

This is my model:
Code:
<?php
class Student_directory_model extends Model {

    function Student_directory_model()
    {
        // Call the Model constructor
        parent::Model();
    }
    
    function getData()
        {
            //Query the data table for every record and row
            $query = $this->db->get('students');
            
            if ($query->num_rows() == 0)
            {
                //show_error('Database is empty!');
            }else{
                return $query->result();
            }
        }
}
?>

This is my view:
Code:
<html>  
<head>  
    <title><?=$page_title?></title>  
</head>  
<body>  
    <h1>&lt;?=$page_title?&gt;</h1>
    <ul>
        &lt;?php foreach($result as $row):?&gt;  
            <li>
                <ul>
                    <li>&lt;?=$row->student_lname?&gt;</li>
                    <li>&lt;?=$row->student_fname?&gt;</li>
                    <li>&lt;?=$row->phone?&gt;</li>
                    <li>&lt;?=$row->parents?&gt;</li>
                    <li>&lt;?=$row->street?&gt;</li>
                    <li>&lt;?=$row->city?&gt;</li>
                    <li>&lt;?=$row->state?&gt;</li>
                    <li>&lt;?=$row->zip?&gt;</li>
                    <li>&lt;?=$row->email1?&gt;</li>
                    <li>&lt;?=$row->cell?&gt;</li>
                </ul>
            </li>
            &lt;!-- li BELOW TO BE SHOWN ONLY WHEN NEEDED --&gt;
            <li>
                <ul>
                    <li>&lt;?=$row->parents_alt?&gt;</li>
                    <li>&lt;?=$row->phone_alt?&gt;</li>
                    <li>&lt;?=$row->street_alt?&gt;</li>
                    <li>&lt;?=$row->city_alt?&gt;</li>
                    <li>&lt;?=$row->state_alt?&gt;</li>
                    <li>&lt;?=$row->zip_alt?&gt;</li>
                    <li>&lt;?=$row->email1_alt?&gt;</li>
                    <li>&lt;?=$row->cell_alt?&gt;</li>
                </ul>
            </li>
        &lt;?php endforeach;?&gt;
    </ul>
&lt;/body&gt;  
&lt;/html&gt;

And this is my controller:
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['result'] = $this->student_directory_model->getData();
            $data['page_title'] = "Student Directory";

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

Thanks in advance for any direction or assistance you might can provide!

#2
[eluser]jedd[/eluser]
Hi Zebake, and welcome to the forums.

You're allowed to put display-logic into your views, okay?

So you can have your second lump of LI's wrapped in a conditional and just test for whether your _alt stuff is present (isset() should do it).

You may want to investigate the helpers, though, as they can provide a bit nicer code for pushing out a bunch of list items.

You may also want to reconsider your database schema - feel free to post it - as I suspect you are doing this inefficiently (I'm guessing that you have two address fields per person, right?).

#3
[eluser]zebake[/eluser]
Wow, fast response, thanks Jedd!
[quote author="jedd" date="1246508924"]
So you can have your second lump of LI's wrapped in a conditional and just test for whether your _alt stuff is present (isset() should do it).
[/quote]
I think I can figure this part out, thank you.

[quote author="jedd" date="1246508924"]
You may want to investigate the helpers, though, as they can provide a bit nicer code for pushing out a bunch of list items.
[/quote]
I will look more into helpers, as well.

[quote author="jedd" date="1246508924"]
You may also want to reconsider your database schema - feel free to post it - as I suspect you are doing this inefficiently (I'm guessing that you have two address fields per person, right?).[/quote]
You're absolutely right, I know there has to be a more efficient / logical way of doing this. Currently I have one table 'students', with 21 fields in it.
Code:
CREATE TABLE IF NOT EXISTS `students` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `student_lname` varchar(255) DEFAULT NULL,
  `student_fname` varchar(255) DEFAULT NULL,
  `parents` varchar(255) DEFAULT NULL,
  `street` varchar(255) DEFAULT NULL,
  `city` varchar(255) DEFAULT NULL,
  `state` varchar(255) DEFAULT NULL,
  `zip` varchar(255) DEFAULT NULL,
  `email1` varchar(255) DEFAULT NULL,
  `email2` varchar(255) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL,
  `cell` varchar(255) DEFAULT NULL,
  `parents_alt` varchar(255) DEFAULT NULL,
  `street_alt` varchar(255) DEFAULT NULL,
  `city_alt` varchar(255) DEFAULT NULL,
  `state_alt` varchar(255) DEFAULT NULL,
  `zip_alt` varchar(255) DEFAULT NULL,
  `email1_alt` varchar(255) DEFAULT NULL,
  `email2_alt` varchar(255) DEFAULT NULL,
  `phone_alt` varchar(255) DEFAULT NULL,
  `cell_alt` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
I also have the feeling I am trying to reinvent the wheel. I searched through the ignited code forum for some type of contact database that I could modify, but I couldn't find anything. In the end, I will be better off building it myself as I obviously need the knowledge. Wink

#4
[eluser]garymardell[/eluser]
I'm not going to write any code currently but give you a idea of how i would do it.

Have a table called student, a table called address and a table called student_address. This is because one student may require many addresses and one address may belong to many students. The student_address table allows this.

The idea is to include where the primary key and foreign keys will be.

Student table
id | primary key
name|
...

Address table
id | primary key
name|
...

student_address table
student_id | composite key
address_id | composite key

Together act as a primary key.

Now to get all the students, you will want to select everything from the students table and from the address table.
Then join the student_address table where student.id = student_address.student_id
And then now join address table where student_address.address_id = address.id

This will return the addresses related to each student, this setup would potentially allow more than 2 addresses for a student (some complicated arrangement maybe.) or just a single address.

#5
[eluser]zebake[/eluser]
[quote author="garymardell" date="1246512259"]The idea is to include where the primary key and foreign keys will be.

Student table
id | primary key
name|
...

Address table
id | primary key
name|
...

student_address table
student_id | composite key
address_id | composite key

Together act as a primary key.

Now to get all the students, you will want to select everything from the students table and from the address table.
Then join the student_address table where student.id = student_address.student_id
And then now join address table where student_address.address_id = address.id

This will return the addresses related to each student, this setup would potentially allow more than 2 addresses for a student (some complicated arrangement maybe.) or just a single address.[/quote]
This sounds great, however right now it is a little bit above my level of comprehension. I'm going to eat dinner and contemplate this a bit more. Maybe it will make more sense once my belly is full. Thank you for your guidance Gary, this definitely sounds like it would offer the scalability that we'll need.

#6
[eluser]slowgary[/eluser]
Welcome to the forums (and CI and PHP)! You've chosen your development path wisely.

Jedd is right (as usual). Your database schema needs work. I'm sure it'll get the job done, but consider a situation where a student has separated parents PLUS a guardian - do you then add a THIRD alt parent to the table? You should instead have a table for students, a table for guardians, and a third table that relates the two. So:
Code:
students
============
student_id //primary key
student_fname
student_lname
student_birthdate
student_whatever

guardians
============
guardian_id //primary key
guardian_fname
guardian_lname
guardian_phone
guardian_address

student_guardians
============
student_id  //index
guardian_id //index
This way allows you to have as many guardians per student, PLUS students can share the same guardian which is likely to be the case all over the place (I'm a poet). Imagine if a guardian needs to update their phone number - previously you would need to find all students who had that guardian and update each row, this way each guardian will have their own distinct information stored.

Now onto your original problem... you can simply add some logic to your view that checks if a variable is set before you attempt to echo it...
Code:
if(isset($row->guardian))
{
     echo $row->guardian;
}

A few other recommendations:

Try to use the most descriptive names for your functions and variables, this will help in the long run when you need to edit your code down the road (another rhyme - I'm on a roll!). So:
Code:
$this->Student_directory_model->get_all_students(); //CI style guide also recommends underscores and never camelCase - I agree
Because getData() is a name you could give EVERY function in your model. And:
Code:
foreach($students as $student)
{
     echo $student->fname;
}
Because all children NEED (not want), but NEED to feel like they belong (it's true!) ;-P

And last but certainly not least, you should throw a few joins into your database query (since we're now working with several tables), and get your results looking like this:
Code:
|  student_id |  lname  |   fname   |  dob     | guardian_fname  |  guardian_lname  |  guardian_phone  |
|     1204    |  smith  |   mikey   | 12/04/91 |  george         |    smith         |    999-999-4321  |
|     1204    |  smith  |   mikey   | 12/04/91 |  susan          |    rogers        |    999-999-3456  |
|     1455    |  decker |   amy     |  2/05/92 |  james & amanda |    decker        |    999-999-3456  |

Then you could iterate through the data with something like this:
Code:
$temp_id = NULL;

foreach($students as $student)
{
     //if we recognize the student ID, it means this student has multiple result rows,
     //(thus multiple guardians in the database).  It also means we've already
     //printed the student's data and we should go right for the guardian
     if($temp_id == $student->student_id)
     {
          echo '-> guardian: '.$student->guardian_lname.', '.$student->guardian_fname;
     }
     //else we haven't seen this student's id yet, which means we
     //should print the student's info plus the guardian for their
     //first row
     else
     {
          echo 'student: '.$student->lname.', '.$student->fname;
          echo '-> guardian: '.$student->guardian_lname.', '.$student->guardian_fname;

          $temp_id = $student->student_id;
     }
}

Make sense?

As for the corresponding database query, I'm a little new to joins and it would require me to actually go read something. Maybe Jedd could help? ;-P (cause I know this is REAL easy for him).

#7
[eluser]zebake[/eluser]
Man, the combination of chicken and pasta in my gut and your explanation was just what I needed! I feel so much more confident in this method, as it answers questions I didn't even think of yet. Thank you all so much for helping to make it click for me! I am going to rework the database first, and then see if I can figure out how to handle that database query. I'm not quite sure how to go about calling the information from three separate tables.

#8
[eluser]slowgary[/eluser]
You'll need to use a few joins in your query, as garymardell stated. It'd be something along these lines (but this is probably wrong):
Code:
$this->db->select('students.*, guardians.fname, guardians.lname, guardians.whatever')
              ->join('student_guardians', 'student_guardians.student_id = students.student_id')
                   ->join('guardians', 'student_guardians.guardian_id = guardians.guardian_id')
                      ->order_by('students.lname, students.fname')
                           ->get('students')
                                ->results();  //or results_array() which would be my preference
I'd of course stick that all on one line and make sure it works. They may need to be left joins or something which can be specified in the third parameter of the join() method, e.g.:
Code:
join('table', 'table.field = table2.field', 'left')
I can never get my joins straight, but you'll figure it out.

#9
[eluser]slowgary[/eluser]
Also - don't eat and write code, it's an equation for obesity. I should know.

#10
[eluser]slowgary[/eluser]
Hey zebake, one more thing...

I mentioned in my comment that I prefer the array way of doing things, e.g.:
Code:
->result_array() //I prefer this way

->result() //over this way

I did a bit of testing and it turns out that the result_array() method uses quite a bit less memory. I'm sure it'd be insignificant if you were just grabbing a few rows, but in your case where you may have several thousand students * X number of guardians per student, you may be looking at a big performance gain in the memory department.

So I recommend using the result_array() method, in which you would access your results like so:
Code:
foreach($students as $student)
{
     echo $student['student_id'];
     echo "<li>{$student['lname']}, {$student['fname']}</li>"; //surround your array variables with curly braces inside of a string
}


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.