Welcome Guest, Not a member yet? Register   Sign In
Loading a model from inside a view - is there a better way?
#1

[eluser]LeePR[/eluser]
It's not really in the spirit of the MVC framework, but I can't think of a better way to do this...

I have a controller method which loads a view for a generic new account setup:
Code:
function createAccount() {
   $this->load->view('create_account');
}
One of things the user will be prompted for is the state where they reside. The list of states is in a MySQL lookup table. State's probably won't change anytime soon, but this is just an example. I would like my VIEW that loads a State MODEL and calls a method that displays an HTML list (dropdown menu) of states i.e. I would rather have
Code:
function createAccount() {
   $this->load->view('create_account');
}
in my CONTROLLER than
Code:
function createAccount() {
   $this->load->model('State');
   $data['stateDropDown'] = $this->State->generateStateListDropDown();
   $this->load->model('Country');
   $data['countryDropDown'] = $this->Country->generateStateListDropDown();
   $this->load->view('create_account'. $data);
}
This is desirable for me because it makes the Controller cleaner, and I would have to repeat the steps involved in generating the dropdowns every time I wanted to use it.

When I try to load a model from within a view, I get the following error:
Code:
A PHP Error was encountered

Severity: Notice
Message: Undefined property: CI_Loader::$State
Filename: views/stateList.php
Line Number: 4

Fatal error: Call to a member function generateStateDropDown() on a non-object in /home/lee/Development/CodeIgniter_1.5.4/system/application/views/stateList.php on line 4

Can someone suggest a cleaner implementation?

Cheers,
Lee
#2

[eluser]coolfactor[/eluser]
I believe you need to use them lowercased.

Code:
$this->state->generateStateListDropDown();
#3

[eluser]LeePR[/eluser]
[quote author="coolfactor" date="1189029520"]I believe you need to use them lowercased.

Code:
$this->state->generateStateListDropDown();
[/quote]

Thanks, but that was really just pseudocode. The same error appears regardless of the case.
#4

[eluser]coolfactor[/eluser]
Really important that you provide _real_ code examples, or it misleads us and we can't help you.

I can't see what else could be wrong.
#5

[eluser]LeePR[/eluser]
[quote author="coolfactor" date="1189030418"]Really important that you provide _real_ code examples, or it misleads us and we can't help you.

I can't see what else could be wrong.[/quote]

Oh, so it's an error in my code? I was thinking that for some reason CI might not let me load models within views. OK here are two scenarios (with real code). My model looks exactly the same for both examples:
Code:
<?php
    class State extends Model {
        
        function Model_state() {
            parent::Model();    
        }
        
        function generateStateDropDown() {
            echo "TEST!";
        }
    }
?>

Scenario 1: The model is loaded within the view. Here's my view:
Code:
<?php
    echo "@ Beginning of view!<br/>";
    //$this->load->model('State');
    //$this->state->generateStateDropDown();
    echo "@ End of view!<br/>";
?&gt;
and here' my controller method:
Code:
function createAccount() {
        $this->load->view('create_account');
        $this->load->model('State');
        $this->state->generateStateDropDown();
    }

This works! And prints out
Quote:Test
@ Beginning of view!
@ End of view!

Scenario 2: I comment out the loading of the model in the controller, and make the view load the model. Here's my view:
Code:
&lt;?php
    echo "@ Beginning of view!<br/>";
    $this->load->model('State');
    $this->state->generateStateDropDown();
    echo "@ End of view!<br/>";
?&gt;
and here's my controller method:
Code:
function createAccount() {
        $this->load->view('create_account');
        //$this->load->model('State');
        //$this->state->generateStateDropDown();
    }

This doesn't work and prints out
Quote:
@ Beginning of view!
A PHP Error was encountered

Severity: Notice
Message: Undefined property: CI_Loader::$state
Filename: views/stateList.php
Line Number: 4

Fatal error: Call to a member function generateStateDropDown() on a non-object in /home/lee/Development/CodeIgniter_1.5.4/system/application/views/stateList.php on line 4
#6

[eluser]coolfactor[/eluser]
Your Scenario #1 was the correct way to do this. You don't want to load models in the view, as you suspected.
#7

[eluser]LeePR[/eluser]
Yes, but that's just means I have to repeat a lot of code in controllers any time I want to do something as simple as generate some code to produce a dropdown list with data coming from a database.
#8

[eluser]coolfactor[/eluser]
[quote author="LeePR" date="1189033957"]Yes, but that's just means I have to repeat a lot of code in controllers any time I want to do something as simple as generate some code to produce a dropdown list with data coming from a database.[/quote]

No, it all depends on how you design your code.

Option #1 - auto-load models

Option #2 - load models in the constructor, making them available across the entire controller.

Option #3 - create a wrapper library that does repetitive work for you
#9

[eluser]LeePR[/eluser]
Thanks for your replies. I'm just going to create some libraries (StateCollection, CountryCollection, etc).




Theme © iAndrew 2016 - Forum software by © MyBB