Want to improve this question? Update the ques开发者_运维百科tion so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this questionI will preface this question with the disclaimer that I know there are many good MVC frameworks (for PHP and other languages) out there. The motivation here is to understand. And sorry for the question's length!
When it comes to dealing with relationship between models (the usual one to one, one to many and etc.),
- Which model is responsible for loading the association?
- How should the association loaded?
For example, a user has an image gallery; there's the user's profile, and the user's pictures. The model may look like this:
class Model_User {
public function load($id) { /* loading code here*/ }
}
class Model_Photographs {
public function load($id) { /* loading code here */ }
}
So for question #1, Which class should load all the photographs that a user has?
If it is in the Model_User class, it means that the class is now dependent on Model_Photographs. Should it be another class?
The second question is how the loading of the relationship is done.
Which is better design?
class Model_User {
public function load_photographs() {
$sql = "SELECT photographs.id, photographs.url, photographs.caption FROM
user_photographs, photographs WHERE
user_photographs.photoid = photographs.id AND
user_photographs.userid = {$this->id}";
/* snipped */
foreach ($results as $photo)
{
$photo = new Model_Photo();
$photo->set($photo);
$this->photos[] = $photo;
}
}
}
Or is this better?
class Model_User {
public function load_photographs() {
$sql = "SELECT photoid FROM user_photographs WHERE
user_photographs.userid = {$this->id}";
/* snipped */
foreach ($results as $photo_id)
{
$photo = new Model_Photo($photo_id);
$this->photos[] = $photo;
}
}
}
The first code uses just one query but requires Model_User to know the fields to fetch from the Photographs table (which isn't its domain at all); the second code is neater, but results in more SQL queries.
MVC frameworks have nothing to do with a data abstraction layer like the Active Record pattern. Your models could use entirely hand-rolled queries to accomplish the same task.
In this specific case, your user should use the Photo model's public interface, and not the Photo table directly. Selecting photos for a given user ID should be done by something like:
class Model_Photo {
public static function find_by_user($user_id) {
// select query goes here
}
}
Your user model could provide a convenience method:
class Model_User {
function photos() {
return Model_Photo::find_by_user($this->id);
}
}
精彩评论