#php #cakephp #cakephp-model
#php #cakephp #cakephp-модель
Вопрос:
Для меня пришло время понять MVC, так что это то, что я пытаюсь сделать; и у меня возникли проблемы с пониманием того, что должна делать модель. Согласно Википедии, модель:
Модель управляет поведением и данными домена приложения, отвечает на запросы информации о его состоянии (обычно из представления) и отвечает на инструкции по изменению состояния (обычно от контроллера). В системах, управляемых событиями, модель уведомляет наблюдателей (обычно представления) об изменении информации, чтобы они могли отреагировать.
И в CakePHP вы предположительно настраиваете модель таким очень простым способом:
<?php
class Posts extends AppModel {
var $name = 'Posts';
}
?>
Итак, если бы мне понадобились, например, последние 10 записей в моей базе данных, я бы создал контроллер, который выглядел бы примерно так:
<?php
class PostsController {
function retrieve_latest($number = 10) {
$posts = $this->Users->find(array(
'fields' => '*',
'order' => 'posts.post_id DESC',
'limit' => $number,
'page' => '1',
'conditions' => array('posts.post_display == 1')
));
$this->set('posts', $posts);
}
}
?>
И этот парень передал бы переменную с именем posts
моему представлению, которое затем отобразило бы ее соответствующим образом. Дело в том, не должна ли моя модель делать что-нибудь еще?, потому что, если бы все было так просто, как это, вообще не было бы смысла в пользовательских моделях, я имею в виду, это просто пустое расширение класса model .
Комментарии:
1. Самый простой способ представить модель — это хранение данных и операции с этими данными, которые не зависят от интерфейса (view). Другими словами, представьте, что вы создаете API для своей бизнес-задачи, не имея конкретных знаний об интерфейсе. Контроллер и представление знают об этом…
2.
AppModel
Экземпляры не имеют ничего общего с модельным уровнем MVC. Это просто экземпляры activerecord.
Ответ №1:
Это «пустое расширение к классу model» уже многое делает: Он подключается к базе данных и выполняет всю мелкую обработку извлечения и сохранения данных. Однако предполагается, что это будет делать намного больше, включая хранение правил проверки, которые применяются всякий раз, когда вы выполняете запись в базу данных, любую обработку данных, необходимую в фильтрах до / после и любую другую пользовательскую бизнес-логику, необходимую в вашем приложении. Модели предназначены для хранения вашей центральной логики бизнес-данных, то есть всего, что не связано с представлением или вводом / выводом, но по сути моделирует основную логику вашего приложения. То, что основы просты в настройке, не означает, что в них нет чего-то большего.
Ответ №2:
Модели также инкапсулируют бизнес-логику и обрабатывают взаимодействия друг с другом. Например, если сообщение содержит комментарии, это то, что будет обработано в модели. Вы бы не хотели, чтобы контроллер извлекал сообщение, а затем извлекал комментарии и собирал их. Это возложило бы ответственность за знание структуры модели на контроллер, где ей не место.
Действительно, существует множество приложений, где модели не содержат большого количества логики, если вообще содержат какую-либо. Модель с простыми полями данных и без бизнес-логики можно рассматривать как DTO (объект передачи данных) или просто «объект», поскольку она не «моделирует» какую-либо бизнес-логику. Это не обязательно плохо, это зависит от потребностей. Многие приложения представляют собой простые приложения с заменой форм на данные и не нуждаются в какой-либо дополнительной логике.
Но если в вашем приложении больше логики, чем просто данные в любой заданной таблице, эта логика присутствует в моделях. Они моделируют не просто данные, они моделируют домен. На самом деле, нередко модели напрямую не имеют одинаковой структуры базы данных. Модели объектно-ориентированы, тогда как базы данных гораздо чаще являются реляционными. Эти две не всегда решают проблемы одинаково. Если вашим моделям нужно точно копировать ваши таблицы, то вы ограничиваете себя более объектно-ориентированными возможностями.
Короче говоря, все, что объясняет, чем занимается бизнес, попадает в модели. Контроллеры — это просто обработчики событий, отвечающие на запросы пользовательского интерфейса. Контроллеры обычно настраиваются для конкретного приложения, тогда как модели должны быть повторно использованы в нескольких приложениях, потому что они представляют ядро бизнес-логики.
Ответ №3:
Если использовать ваш пример, то идеальными являются тонкие контроллеры и толстые модели. Это означает, что ваш код в идеале должен быть переработан следующим образом:
class Post extends AppModel {
var $name = 'Post';
function retrieveLatest($limit = 10) {
return $this->find('all', array(
'order'=>'Post.id'=>'DESC',
'limit'=>$limit
);
}
}
class PostsController extends AppController {
function retrieve_latest($limit) {
$posts = $this->Post->retrieveLatest($limit);
$this->set(compact('posts'));
}
}
Ваш контроллер не должен беспокоиться о сложных деталях того, что необходимо для извлечения самых последних, это бизнес-логика и выполняется в модели, рядом с данными. Еще одним преимуществом является то, что вы также можете извлекать последние записи из любой связанной модели:
$posts = $this->User->Post->retrieveLatest();
Вы могли бы даже пойти на один этап дальше и переместить код retrieveLatest() в свою AppModel, чтобы каждая модель наследовала его:
class AppModel extends Model {
function retrieveLatest($limit = 10) {
$model = $this->alias;
return $this->find('all', array(
'limit'=>$limit,
'order'=>array(
$model . ".id"=>'DESC'
)
);
}
}
Как правило, каждый раз, когда вы обнаруживаете, что создаете запросы в своих контроллерах, перемещайте их в модель и присваивайте им описательное имя.