Welcome Guest, Not a member yet? Register   Sign In
Should Views access data from Models using DB column names?
#1

[eluser]mhiggins[/eluser]
I have developed a large part of my application now, making sure to place all DB query code into a model, with roughly one model per DB table. As in much of the sample code provided in these forums and around the web, my views are displaying data from the models by referencing column names from the DB results object that the model passes to the controller and then onto the view.

For example (illustrative only):

View
Code:
<table>
<tr>
<td>&lt;?php echo $customer->fullname; ></td>        // fullname is a DB column name
<td>&lt;?php echo $customer->phone_number; ></td>    // phone_number is a DB column name
</tr>
</table>

Controller
Code:
$data['customer'] = $this->customer_model->get_customers();        // returns a DB $result() object

and now I need the model to return the results of a query that joins multiple tables with non-unique column names such as:

Code:
DB Structure
-------
Customer.id
Customer_order.id

which can be solved by using aliases but I now wonder is it in fact correct (according to MVC separation ideals) for the view to require knowledge of DB column names? This would mean if I modify a DB column name, I must change not only the model, but also any view that uses that data.

So, my (long-winded) question is: Shouldn't the Model be modifying its own variables with the results of a DB query and the view accesses the model variables directly, rather than the DB column names?

e.g.

Model
Code:
*Customer model*

var $fullname;
var $customer_id;
var $customer_order_id;
...

View
Code:
<table>
<tr>
<td>&lt;?php echo $this->customer_model->fullname; ?&gt;</td>
<td>&lt;?php echo $this->customer_model->customer_order_id; ?&gt;</td>
</tr>
</table>

I've looked around the forums and on Stackoverflow etc but cannot find a clear opinion or guideline from someone to indicate if it should be done this way.

I would be grateful to anyone who can weigh-in on which is the most correct way to go about this as this is affects the plumbing of my whole app.

Cheers,
Mike
#2

[eluser]rogierb[/eluser]
I would go with aliases. As for an example I have a report model and it is used to gather data for numerous complex reports using many tables. There are queries that maybe use 10% of field names and 90% aliases and have about 35-40 different result fields. If I where to put them in variables, I would get hundreds of variables in the model.

Not really workable. As for views accessing models, wouldnt this break the MVC principle?
#3

[eluser]TheFuzzy0ne[/eluser]
I don't think you will ever find a straight answer to your question - opinions vary.

My personal preference is to keep all calls to the model in the controller. That's where I make sure I have the data I need before throwing it into the view. If you want to stick to MVC, this means keeping the Model separate from the View. For me, the controller is the glue between the pieces. If I had my way, it would be called MCV (the controller being in the middle).

However, it certainly is possible to access the model from within your view, but I'd suggest only calling on set model variables, not methods. If I wanted to see what data was used in a certain page, the first place I'd look, would be in the controller. Wouldn't you?

Hope this helps.
#4

[eluser]wiredesignz[/eluser]
Quote:As for views accessing models, wouldnt this break the MVC principle?
Quote:For me, the controller is the glue between the pieces. If I had my way, it would be called MCV (the controller being in the middle)

Obviously nobody has read wikipedia: http://en.wikipedia.org/wiki/Model-view-controller

Quote:The controller notifies the model of the user action, possibly resulting in a change in the model's state. (for example, the controller updates the user's shopping cart).

A view uses the model indirectly to generate an appropriate user interface (for example, the view lists the shopping cart's contents). The view gets its own data from the model. The model and controller have no direct knowledge of the view.

View renders the model into a form suitable for interaction, typically a user interface element. Multiple views can exist for a single model for different purposes.

Controller processes and responds to events (typically user actions) and may indirectly invoke changes on the model.

You may access your model from within your view, the view can be aware of the column names.

However storing variables discretely is very cumbersome I would recommend storing the entire resultset in the model (not controller) and using a loop in the view to retrieve it. (testing for the existence of each column as you go)
#5

[eluser]mhiggins[/eluser]
rogierb. Good point. I have made use of aliases a few times but hesitated to write a huge query with 20 aliases in it as it felt wrong for some reason. Knowing someone else is doing it this way removes some of that hesitation. This was my fallback way of doing it, and I think I will go with it.

TheFuzzy0ne. Yep, keeping the separation is key, as the application is likely to grow larger in future and any modularity I can inject now will be helpful down the track.

Thanks for the quick responses.
#6

[eluser]mhiggins[/eluser]
Quote:However storing variables discretely is very cumbersome I would recommend storing the entire resultset in the model (not controller) and using a loop in the view to retrieve it. (testing for the existence of each column as you go)

So, would that be something like the below code straight in the view file?

View
Code:
foreach ($this->customer_model->get_customers() as $customer)
    {
        // loop through the results
    }
#7

[eluser]Dam1an[/eluser]
That would call the get_customers model every time, giving you a new result (causing an infinite lop)
If anything, you should Do the call once, convert it to a result (or result array) and then use the result in the loop (I do the first 2 parts in the controller, but thats just me)
#8

[eluser]wiredesignz[/eluser]
The initial call to the model is in the controller to obtain the resultset.

View:
Code:
&lt;?php
        while ($account = $users_model->iterate()):
            
            $is_active = ($account->uid == $active_uid);
            $is_admin  = ($account->privileges == 3);
    ?&gt;

Users_model:
Code:
function iterate()
    {        
        if (list($key, $users_account) = each($this->resultset))
        {
            $users_account->hidden_pwd = str_repeat('*', 6);
            
            return $users_account;
        }
    }
Note: The users_model data never enters the controller.
#9

[eluser]xwero[/eluser]
I've been thinking about this for a long time as it didn't felt right to change a view if a field name changed in the database and sometimes field names are too verbose to use in the view.

Aliases are still connected to the queries as that is the place of origin. If you let the controller be the place of origin it will be aware of more than is needed and then all model methods have to be called by the controllers. Which isn't always the case as wiredesignz showed.

I decided for myself it's ok to have db fieldnames in the views as they are (almost) solid after the development is done and i couldn't find a way yet to make the view variables independent from the models without a big performance loss or a big configuration.
#10

[eluser]Dam1an[/eluser]
Also, another reason why I think its ok to use column names in the view is
I would use the same name anyway!

I choose short but descriptive names as database columns, such as first_name, last_name, email etc, the sort of things you'd want to see in a view Smile




Theme © iAndrew 2016 - Forum software by © MyBB