Welcome Guest, Not a member yet? Register   Sign In
Using variables to load queries from models....
#1

[eluser]the future darlo manager[/eluser]
Just wondering if this is possible.

I have a few tables that I want to query. I was wondering if it would be possible to set an array with the table names in and then use a for loop to dynamically set the queries?

Example below to try and show what I am on about. Just can't seem to get the syntax right and need a little help...

Code:
//Sets up an array of submission names
$query_names = array("teacher", "learner");
            
foreach ($query_names AS $query_names)
{
    $submission_name =  $query_names.'_submission';
    $submission_model_name = $query_names.'_submissions_model';
                                            
    //Loads the query to get the selected teacher submission
   $data["$submission_name"] = $this->"$submission_model_name"->getSelectedUsersTeacherSubmission($user_id);
                
    //if ($data[$submission_name]->num_rows() == 1)
    {
        echo "Something found";
    } else {
    echo "Not Found";
    }
                
}

Obviously I would not each stuff out in the model but just want to get a result for now...
#2

[eluser]Clooner[/eluser]
look into the php function call_user_func to dynamically call classes and its methods
#3

[eluser]jedd[/eluser]
Howdi. If you're not using AR, then you don't need to stick with the one-model-per-table paradigm, so you could wrap up similarly-purposed tables to be handled by a single model. This model handles groupings of tables that have similar information. Then you could pass whatever identifying information you need to the model, and let it work out how to get the data it needs.

This is elegant because it saves the controller needing to know details regarding the database layout, it means you can modify the database layout later and only have to modify the model, and you don't have to do all this messing about. If you have so many models (all of which are hand-crafted) that you need to talk to them via variables .. this hints at a design problem.

Some pointers follow, but I'd really suggest you approach this differently anyway.

Code:
$query_names = array("teacher", "learner");

Note you could create an associative array that includes the model name. "teacher"=>"teacher_model", etc. Of course, creating the model name algorithmically is cleaner, but this would read better and allow some flexibility.

Code:
foreach ($query_names AS $query_names)

The second variable really should be different to the first. Typically you remove the 's' from the end.

Code:
$data["$submission_name"] = $this->"$submission_model_name"->getSelectedUsersTeacherSubmission($user_id);

You don't want the quotation marks around the $submission_* variables.
#4

[eluser]the future darlo manager[/eluser]
Right, based on the advice I decided to bundle the queries together in one place.

Code:
class Submissions_model extends Model{
    
    function Submissions_model() {
        parent::Model();
    }
    
    function getUserSubmissions($user_id) {    
        $query1 = $this->db->query("SELECT *,
        DATE_FORMAT(date_started, '%b %D, %Y at %h:%i %p') AS start_date,
        DATE_FORMAT(date_updated, '%b %D, %Y at %h:%i %p') AS update_date
        FROM teacher_submissions
        WHERE user_id = '$user_id'
        LIMIT 1");
        
        if ($query1->num_rows() == 1)
        {
            foreach ($query1->result_array() as $row)
            {
                //$submission_data[] = $row;
                $submission_data['teacher'] = $row;
            }
        }
        
        $query2 = $this->db->query("SELECT *,
        DATE_FORMAT(date_started, '%b %D, %Y at %h:%i %p') AS start_date,
        DATE_FORMAT(date_updated, '%b %D, %Y at %h:%i %p') AS update_date
        FROM learner_submissions
        WHERE user_id = '$user_id'
        LIMIT 1");
        
        if ($query2->num_rows() == 1)
        {
            foreach ($query2->result_array() as $row)
            {
                    //$submission_data[] = $row;
                    $submission_data['learner'] = $row;
            }
        }
        
        return $submission_data;
    }
        
}

Using a print_r() command in my controller I can now see something similar to this below...

Code:
Array
(
    [teacher] => Array
        (
            [submission_id] => 3
            [user_id] => 1
            [date_started] => 2009-02-17 11:58:26
            [date_updated] => 2009-03-10 13:28:35
            [step_1] => Y
            [step_2] => Y
            [step_2_question_a] => Y
            [step_2_question_b] => Y
            [step_2_question_c] => Y
            [step_3] => Y
            [submitted] => N
            [nominator_name] => Kevin Luff
            [nominator_email] => [email protected]
            [nominator_tel_text] => 01325 461653
            [how_does_nominator_know_teacher] => Taught in my BSL class.
            [teachers_name] => Stuart Luff
            [teachers_email] => Don't know...
            [teachers_tel_text] => 01325 387000
            [teachers_centre] => Darlington College
            [question_a] => Vivamus et est sit amet risus
            [question_b] => Lorem ipsum dolor sit amet
            [question_c] => Eduardo has describe
            [supporting_info] => Hello.
            [start_date] => Feb 17th, 2009 at 11:58 AM
            [update_date] => Mar 10th, 2009 at 01:28 PM
        )

    [learner] => Array
        (
            [submission_id] => 3
            [user_id] => 1
            [date_started] => 2009-02-18 13:58:56
            [date_updated] => 2009-03-10 13:40:40
            [step_1] => Y
            [step_2] => Y
            [step_3] => Y
            [submitted] => N
            [nominator_name] => Kevin Luff
            [nominator_email] => [email protected]
            [nominator_tel_text] => 01325 461653
            [how_does_nominator_know_learner] => Some time, maybe four years?
            [learners_name] => Stuart Luff
            [learners_email] => N/A
            [learners_tel_text] => 01325 387001
            [learners_centre] => Darlington
            [step_2_question] => Lorem ipsum dolor sit amet,
            [supporting_info] => Pellentesque massa.
            [start_date] => Feb 18th, 2009 at 01:58 PM
            [update_date] => Mar 10th, 2009 at 01:40 PM
        )

)

I only really need bits like the 'submitted', start_date, update_date and submission_id but don't know how to go about using the values in my controller or sending them to the view. Controller is below;

Code:
function show()
    {
        //Gets the user id from the url
        $user_id = $this->uri->segment(3, NULL);
        
        //Finds out if the sort by setting has been issued from the URL
        if (!isset($user_id)) {
            redirect('users/showall', '');
        }
        
        //Loads the query to get the selected user
        $data['user'] = $this->Nomination_users_model->getSpecificUser($user_id);
        
        //Checks to see if there are records to return
        if ($data['user']->num_rows() == 1)
        {
            //Gets the user details for the view
            $row = $data['user']->row();            
            $data['user_id'] = $row->user_id;
            $data['email'] = $row->email;
            $data['first_name'] = $row->first_name;
            $data['last_name'] = $row->last_name;
            $data['date'] = $row->date;
            
            //Loads the teacher, learner, JMR, organisational and communication professionals model
            $this->load->model('Submissions_model');
            
            //Loads the queries
            $data['submissions'] = $this->Submissions_model->getUserSubmissions($user_id);

            print_r($data['submissions']);
            
            //Loads the views
            $this->load->vars($data);
            $this->load->view('admin_header.php');
            $this->load->view('show_user.php');
            $this->load->view('admin_footer.php');
            
        }
    
    }

Would appreciate any help as I've been looking at this for ages (maybe too long now).
#5

[eluser]jedd[/eluser]
Okay, some of this - I'll throw some ideas at you, but someone else may well correct me later.

[quote author="the future darlo manager" date="1236975541"]Right, based on the advice I decided to bundle the queries together in one place.[/quote]

In addition to having queries in the model, you might want to have multiple methods to provide different types of information back. You might want to look at phpdoc - I've started using this lately and it's very useful for inline documenting of functions - parameters, return values, etc. getUserSubmissions returns one submission, right? And that's meant to include a Teacher and a Learner array (as shown), yes?

Your user->row stuff in the controller - shouldn't be there. Your model should be returning an array, and you foreach() your way through that array. This will also make display of those data (in the view, later) much easier.


Code:
function getUserSubmissions($user_id) {    
        $query1 = $this->db->query("SELECT *,
        ...
        FROM teacher_submissions
        WHERE user_id = '$user_id'
        LIMIT 1");

Consider:
o SELECTing only the data that you need
o if user_id is the PK, you don't need LIMIT
o if user_id is not the PK, you might want to remove LIMIT so you can test for database consistency


Rather than this:
Code:
if ($query1->num_rows() == 1)
        {
            foreach ($query1->result_array() as $row)
            {
                //$submission_data[] = $row;
                $submission_data['teacher'] = $row;
            }
        }

Why not just:
Code:
if ( $query1->num_rows() )
        {
            $submission_data['teacher'] = $query1->row_array();
        }


Instead of just returning data (regardless of whether it exists) with this:
Code:
return $submission_data;

Why not add some meaning to the return value:
Code:
if ($query2->num_rows())
                return $submission_data;
        else
                return FALSE;



Rather than this:
Code:
function show()
    {
        //Gets the user id from the url
        $user_id = $this->uri->segment(3, NULL);
        
        //Finds out if the sort by setting has been issued from the URL
        if (!isset($user_id)) {
            redirect('users/showall', '');
        }

How about this:
Code:
function show ( $user_id = NULL )
    {
        //Finds out if the sort by setting has been issued from the URL
        if (! $user_id) {
            redirect('users/showall', '');
        }


Instead of this (in the controller):
Code:
if ($data['user']->num_rows() == 1)
        {
            //Gets the user details for the view
            $row = $data['user']->row();            
            $data['user_id'] = $row->user_id;
            $data['email'] = $row->email;
            ...

As discussed, you want to avoid -> row calls within the controller. The model should be returning an array, so at this point you can just copy the $user array into your $data array, and the $data array will later feed the view, right?

So you'd replace the above with something like:
Code:
$data['user'] = $row_array_result;   // (word it better, it's the thing that came back from the model earlier)

In fact you can assign $data['user'] with the output of the model call directly. You still want to test it to make sure that it's got valid data in it (again, in the model you'd return FALSE if you have a problem, or can't find a match etc).


We may be approaching the meat of your question here.
Code:
//Loads the views
            $this->load->vars($data);
            $this->load->view('admin_header.php');
            $this->load->view('show_user.php');

Rather than load->vars($data) you can pass the $data to each view - this is handy if you want to provide less data to each view, but of course not necessary. I think you also need one less .php in the call. So something like :
Code:
$this->load->view('show_user' , $data);

Within your view, as per the user manual, you don't see $data - you see only the array elements. So for example, the variable $user would exist, and be an array that contains keys such as 'user_id' and 'email', and so on.

Does this make more sense?




Theme © iAndrew 2016 - Forum software by © MyBB