I just realized that i may not be following best practices in regards to the MVC pattern.
My issue is that my views "know" information about my database
Here's my situation in psuedo code...
My controller invokes a method 开发者_运维问答from my model and passes it directly to the view
view.records = tableGateway.getRecords() // gets array of records
view.display()
in my view
each records as record
print record.name
print record.address
...
In my view i have record.name and record.address, info that's hard-coded to my database. Is this bad?
What other ways around it are there other than iterating over everything in the controller and basically rewriting the records collection. And that just seems silly.
Thanks
EDIT
Heres an actual view
<?php foreach( $categories as $category ): ?>
<tr>
<td><?php echo $category['name'] ?> </td>
<td><?php echo $category['fields'] ?> </td>
<td><?php echo $category['records'] ?></td>
<td><a href="/category/view/<?php echo $category['id'] ?>/<?php echo url::title( $category['name'] ) ?>/">View</a></td>
</tr>
<?php endforeach; ?>
So a simple loop through the data won't work, i need to capture certain fields of the sql result in my view.
Is there a way around this? It makes me feel dirty.
I'd say it's not bad to have such info hardcoded if you need to have it quick and dirty.
But consider having generic class for views with method that takes your data from db and some array describing which columns to use. Then in the children classes (UserView, PostView, WhateverTableNameView) you could call this base method with array containing "Name", "Address" etc.
Pardon me if I am talking Python gibberish, I came to this question from PHP tag ;) More or less like this
class BaseView {
public function display(& $data, array $columnNames) {
foreach($data as $row) {
foreach($columnNames as $c) {
echo $row->$c; // or $row[$c] or whatever your data is, I'm assuming objects
}
echo "\n";
}
}
class UserView extends BaseView{
public function display(& $data) {
parent::display($data, array('Name', 'Address');
}
}
The nice things here:
- Need one more column? Make sure you query for it, then modify 1 line in UserView.
- Need to have text for HTML column labels (<th> stuff) - it's already here.
- $data could be resource descriptor (think while($rs.nextRow())) and not neccessarily full array that might occupy a lot of memory and take time to pass around from one function to another.
- if you go for nice looking HTML tables around these records, you have unified look & feel across application as there's only one place where you define them.
If for some reason this doesn't appeal to you, the truly generic solution is to have indexes instead of column names. $data[$i][0], $data[$i][1] and so on... Most database APIs offer possibility to query for columns as names, as numbers or both. For PHP + MySQL see examples on http://www.php.net/manual/en/function.mysql-fetch-array.php
But this will bite you in the a$$ sooner or later because you lose metadata info. Let's say you want later to wrap your "names" into links:
echo '<a href="user/',$record['id'],'">',$record['name'],'</a>';
Good luck doing this in reusable way without column names...
With getters/setters and a piece of code to map the record fields to them you can remove this, but you'll add some complexity.
The real question is: Do i need to rename field names at all?
With some planning/thinking/feedback it shouldn't be hard to find appropriate names for your fields that survive the applications lifetime. However, if the semantics of the field change you should add a new field. This has also the advantage that you can clearly document the deprecation of it and lead the programmer to the new one.
精彩评论