Что она делает? Модель разделяет область кода от представления, отделяя код приложения.
Модель это общая точка доступа к базе данных, а именно, к определенной таблице в базе данных. По умолчанию, каждая модель использует таблицу, чье имя – это множественное число от имени модели, например: модель 'User' использует таблицу 'users'. Модель может также включать в себя правила верификации данных, информацию об ассоциациях, и индивидуальные методы к таблице, которую использует. Вот как простая модель 'User' может выглядеть в Cake:
<?php//AppModel дает вам всю функциональность моделей Cakeclass User extends AppModel{
// Всегда полезно включать эту переменную.
var $name = 'User';
// Это используется для верификации данных, подробнее в соответствующей главе.
var $validate = array();
// Вы также можете объявить ассоциации. // Посмотрите раздел 6.3 для более подробной информации.
var $hasMany = array('Image' => array(
'className' => 'Image') );
// Вы также можете включить собственные функции:
function makeInactive($uid) {
//Вставьте свой код сюда...
}}
?>
Со стороны PHP, модели это классы расширения App Model класса. App Model класс изначально объявлен в директории cake/, но если вы хотите создать собственный, поместите его в app/app_model.php. Он должен включать в себя методы, которые будут делиться двумя или более моделями. Он сам по себе расширит класс Модели которая находится в стандартной библиотеке Cake в cake/libs/model.php.
Этот раздел будет рассказывать о самых часто используемых функциях моделей Cake, не стоит забывать, что полезно использовать http://api.cakephp.org для полной справки.
<?phpclass Post extends AppModel{ var
$name = 'Post'; function
hide ($id=null) {
if (
$id) {
$this->id = $id;
$this->saveField('hidden', '1'); }
}
function
unhide ($id=null) {
if (
$id) {
$this->id = $id;
$this->saveField('hidden', '0'); }
}
}
?>
Когда опция $recursive установлена на целое значение выше 1, операция findAll() попытается вернуть модели ассоциированные с найденным операцией findAll(). Если у ваших данных несколько владельцев, то рекурсив операции findAll() в вашей модели Property возвратит все ассоциированные модели.
Если опция $recursive установлена на целое значение между 1 и 3, операция find() попытается вернуть модели ассоциированные с найденными операцией find(). Рекурсивный поиск может работать на три уровня вглубь. Если у ваших данных несколько владельцев, рекурсивная операция find() в вашей модели Property вернет ассоциативные модели до трех уровней вглубь.
<?$this
->Post->findByTitle('My First Blog Post');$this->Author->findByLastName('Rogers');$this->Property->findAllByState('AZ');$this->Specimen->findAllByKingdom('Animalia');?>
Результатом будет масив, форматированный как в find() или findAll().
Это полезно в случае, когда вы хотите разместить ссылки «Предыдущее» и «Следующее», что позволят пользователям путешествовать по каким-то упорядоченным, последовательным данным в вашей модели. Это работает только с полями, имеющими нумерацию или датирование.
<?class ImagesController extends AppController{ function
view($id) {
// Скажем мы хотим показать изображение...
$this->set('image', $this->Image->find("id = $id");
// Но также мы хотим чтобы у нас были предыдущие и следующие изображения...
$this->set('neighbours', $this->Image->findNeighbours(null, 'id', $id); }
}
?>
Это дает полный массив $image['Image'], вместе с $neighbours['prev']['Image']['id'] и $neighbours['next']['Image']['id'] в нашем отображении.
<?$this
->set(
'Roles',
$this->Role->generateList(null, 'role_name ASC', null, '{n}.Role.id', '{n}.Role.role_name'));
?>
//Это может вернуть что-то похожее на это:
Пожалуйста отметьте что операция read() сделает выборку только с первого уровня ассоциативных моделей, не обращая внимания на значение $recursive в модели. Чтобы получить дополнительные уровни, используйте find() и findAll().
<?phpclass Post extends AppModel{ var
$name = 'Post'; function
posterFirstName() {
$ret = $this->query("SELECT first_name FROM posters_table WHERE poster_id = 1");
$firstName = $ret[0]['first_name']; return
$firstName; }
}
?>
Самое простой массивный запрос выглядит так:
Структура даже не требует объяснений: это найдет любой пост, название которого будет соответствовать This is a post. Отметьте, что мы могли использовать только title как имя поля, но создавая запросы, полезно указывать и имя модели, так как это улучшает четкость кода и помогает предотвратить несостыковки в будущем. Что насчет других типов соответствий? Все так же просто. Скажем мы хотим найти все посты где в названии нет This is a post:
Все что мы добавили это '<>' перед выражением. Cake может проанализировать любой действительный оператор SQL, включая выражения как LIKE, BETWEEN или REGEX, так же как вы оставляете место между оператором и выражением или значением. Одно исключение в стиле (...) соответствия. Скажем вы хотите найти посты, названия которых соответствуют одному из списка значений:
Добавление дополнительных фильтров в условия это так же просто как добавления дополнительных пар ключ/значение в массив:
<?array(
"Post.title" => array("First post", "Second post", "Third post"),
"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks")))
?>
По умолчанию, Cake добавляет многократные условия с логическим AND; что значит, фрагмент ниже будет соответствовать только постам, что были созданы в прошедшие две недели, и название которых соответствуют одному из данных. Однако, мы можем также легко найти посты, соответствующие любому условию:
<?array(
"or" => array
(
"Post.title" => array("First post", "Second post", "Third post"),
"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks")) )
)
?>
Cake принимает все действующие логические операторы SQL, включая AND, OR, NOT, XOR и т.д., и они могут быть в верхнем или нижнем регистре, как вам больше нравится. Скажем у вас есть hasMany/belongsTo отношения между Posts и Authors, результат поиска в Posts будет в LEFT JOIN. Скажем, вы хотите найти все посты, что содержат ключевое слово или которые были созданы в прошедшие две недели, но вы хотите ограничиться постами, написанными Бобом:
<?array (
"Author.name" => "Bob", "or" => array (
"Post.title" => "LIKE %magic%",
"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks") )
)
?>
<?Array(
[
ModelName] => Array (
[
fieldname1] => 'value'
[fieldname2] => 'value'
))
?>
В случае, если вам нужно чтобы ваши данные были отправлены в контроллер таким способ, будет проще использовать HTML Хелпер, потому что он создает элементы формы, называя их именно так, как ожидает этого Cake. Вы не обязаны его использовать, однако: только убедитесь, что имена элементов формы выглядят как data[Modelname][fieldname]. Однако, использование $html->input('Model/fieldname') — проще.
Форма данных автоматически форматируется и помещается в $this->data в ваш контроллер, так что сохранение ваших данных из веб-формы – это дело одного клика. Функция редактирования для вашего собственного контроллера может выглядеть так:
<?function edit($id) {
//Заметьте: Нужная модель автоматически загружена для нас в $this->Property. // Проверяем есть ли у нас форма для данных...
if (empty($this->data)) {
$this->Property->id = $id;
$this->data = $this->Property->read();//размножаем поля формы для данной строки
} else {
// Вот здесь мы пытаемся сохранить наши данные. Автоматическая верификация.
if ($this->Property->save($this->data['Property'])) {
//Выводить сообщение и перенаправление.
$this->flash('Ваша информация сохранена.', '/properties/view/'.$this->data['Property']['id'], 2); }
//если в каких-то полях данные не правильные или сохранение провалилось, форма сообщит
}}
?>
Обратите внимания как операция сохранения помещена внутрь условия: когда вы пытаетесь сохранить данные в модель, Cake автоматически пытается проверить их, используя правила, которые ему предоставили. Узнать больше о проверке данных, вы можете в главе «Верификация данных». Если вы не хотите чтобы save() пытался проверить ваши данные, используйте save($data, false)
Другие полезные функции сохранения:
Если эта модель ассоциирована с другими моделями, и ключ зависимости был установлен в ассоциативном массиве, этот метод также удалил те ассоциативные модели, если $cascade присвоено значение true.
Возвращает true при успешном выполнении.
Одним из использований beforeSave может быть формирования времени и даты для сохранения в специфическом месте базы данных:
<?// Дата/время поля созданы HTML-хелпером:// Этот код будет виден в отображении
$html->dayOptionTag('Event/start');$html->monthOptionTag('Event/start');$html->yearOptionTag('Event/start');$html->hourOptionTag('Event/start');$html->minuteOptionTag('Event/start');/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/// Функция колбека модели, используемая для того, чтобы сшить
// данные о дате в месте для сохранения.
// Этот код будет виден в модели Event:
function beforeSave(){
$this->data['Event']['start'] = $this->_getDate('Event', 'start'); return
true;}
function
_getDate($model, $field){
return
date('Y-m-d H:i:s', mktime(
intval($this->data[$model][$field . '_hour']),
intval($this->data[$model][$field . '_min']),
null,
intval($this->data[$model][$field . '_month']),
intval($this->data[$model][$field . '_day']),
intval($this->data[$model][$field . '_year'])));}
?>
Представьте что у вас есть группы (Groups) в которых множество пользователей (Users), у которых будет много статей (Articles).
Model::recursive options
$recursive = 0 Cake делает выборку данных группы
$recursive = 1 Cake делает выборку группы и ассоциирует ее с пользователями
$recursive = 2 Cake делает выборку группы, ассоциирует ее с пользователями, а пользователи ассоциируются со статьями
Есть четыре типа ассоциаций в Cake PHP:
Когда ассоциации между моделями объявлены, Cake автоматически сделает выборку моделей пребывающих в отношении с моделью, с которой вы работаете. Например, если модель Post имеет отношения к модели Author используя тип ассоциации hasMany, делая запрос к $this->Post->findAll() в контроллере будет сделана как выборка записей Post, так и всех записей Author, к которым они относятся.
Чтобы корректно использовать ассоциации, лучше следовать схеме присвоения имен Cake PHP. Если вы следуете этой схеме, вы можете пользоваться скаффолдингом для визуализации данных вашего приложения, потому что скаффолдинг вылавливает и использует ассоциации между моделями. Конечно же вы всегда можете настроить ассоциации моделей для работы, если не используете схему присвоения имен Cake PHP, но мы прибережем эти советы на потом. А пока, давайте просто следовать схеме. Схема присвоения имен, которая нас волнует – это сторонние ключи, имена моделей и таблиц.
Вот обзор того, что Cake ожидает от имен этих разных элементов: (взгляните на «Соглашение Cake» для подробной информации о присвоении имен)
Скаффолдинг Cake PHP ожидает, что ваши ассоциации построены в том же порядке, что и колонки. То есть, если у меня есть Articles с типом ассоциаций belongsTo, то есть принадлежит трем другим моделям (Author, Editor и Publisher), мне понадобятся три ключа: author_id, editor_id и publisher_id. Скаффолдинг ожидает, что ваши ассоциации происходят в том же порядке, что и ключи в таблице (наприер, сначала Author, второй Editor и последний Publisher).
Чтобы показать как некоторые из этих ассоциаций работают, давайте продолжим использовать приложение блога как пример. Представьте, что мы собираемся создать простую систему управления пользователями блога. Я предполагаю это будет не для того, чтобы следить за пользователями, а для того чтобы у каждого пользователя был ассоциированный профиль (Profile, пользователь hasOne профиль). Пользователи также смогут создавать комментарии оставляя ассоциацию с ними (пользователь hasMany комментарии). Сделав пользовательскую систему, мы переходим к тому, чтобы позволить постам относится к тег-объектам, используя тип ассоциаций hasAndBelongsToMany (имеетИПринадлежитМногим, то есть пост имеет и принадлежит многим тегам).
/app/models/user.php hasOne<?php
class User extends AppModel{ var
$name = 'User'; var
$hasOne = array('Profile' => array(
'className' => 'Profile',
'conditions' => '',
'order' => '',
'dependent' => true,
'foreignKey' => 'user_id'
) );
}
?>
Массив $hasOne это то, что Cake использует для создания ассоциации между User и Profile моделями. Каждый ключ в массиве позволяет настроить ассоциацию:
Теперь когда мы выполняем запросы find() или findAll(), используя Profile модель, мы также увидим здесь и ассоциативную модель User:
<?$user
= $this->User->read(null, '25');print_r($user);?>
<?/app/models/profile.php belongsTo<?phpclass Profile extends AppModel{ var
$name = 'Profile'; var
$belongsTo = array('User' => array(
'className' => 'User',
'conditions' => '',
'order' => '',
'foreignKey' => 'user_id'
) );
}
?>
Массив $belongsTo это то, что Cake использует для создания ассоциаций между User и Profile моделями. Каждый ключ в массиве позволяет вам настраивать ассоциацию:
Теперь, когда мы выполняем запросы find() или findAll(), используя Profile модель, мы должны увидеть нашу ассоциированную модель User:
<?$profile
= $this->Profile->read(null, '4');print_r($profile);?>
/app/models/user.php hasMany<?php
class User extends AppModel{ var
$name = 'User'; var
$hasMany = array('Comment' => array(
'className' => 'Comment',
'conditions' => 'Comment.moderated = 1',
'order' => 'Comment.created DESC',
'limit' => '5',
'foreignKey' => 'user_id',
'dependent' => true,
'exclusive' => false,
'finderQuery' => ''
) );
// Вот отношение hasOne, которое мы объявили раньше...
var $hasOne = array('Profile' => array(
'className' => 'Profile',
'conditions' => '',
'order' => '',
'dependent' => true,
'foreignKey' => 'user_id'
) );
}
?>
Массив $hasMany это то, что использует Cake для создания ассоциаций между User и Comment моделями. Каждый ключ массива позволяет вам настроить ассоциацию:
Теперь когда мы выполняем запросы find() и findAll(), используя модель User, мы должны увидеть все ассоциированные комментарии:
<?$user
= $this->User->read(null, '25');print_r($user);?>
Хоть мы и не документируем процесс, но было бы очень полезно объявить ассоциацию Comment belongsTo User, чтобы каждая из моделей видела друг друга.
Разница между hasMany и hasAndBelongsToMany в том, что с hasMany ассоциированная модель не общая. Если User hasMany Comments, это *только* пользователь ассоциирован с теми комментариями. С НАВТМ, ассоциированная модель – общая. Это хорошо для того, что мы будем делать дальше: ассоциировать модель Post с моделью Tag. Пока модель Tag принадлежит модели Post, мы не хотим чтобы она была 'истощена', мы хотим продолжить, ассоциировать ее с другими постами.
Для этого там нужно установить корректные таблицы для этой ассоциации. Конечно, нам понадобится таблица tags для модели Tag, и таблица posts для постов, но также нам будет нужна связная таблица для этой ассоциации. Схема присвоения имен для связных таблиц НАВТМ это [имя первой модели во множественном числе]_[имя второй модели во множественном числе], где имена моделей должны идти в алфавитном порядке:
Связные таблицы HABTM должны состоять минимум из двух сторонних ключей моделей, которые они связывают. Для нашего примера, post_id и tag_id это все что нам нужно.
Вот как будут выглядеть дампы SQL для нашего Posts HABTM Tags примера:
--
-- Table structure for table `posts`
--
CREATE TABLE `posts` (
`id` int(10) unsigned NOT NULL auto_increment,
`user_id` int(10) default NULL,
`title` varchar(50) default NULL,
`body` text,
`created` datetime default NULL,
`modified` datetime default NULL,
`status` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`)
) TYPE=MyISAM;
-- --------------------------------------------------------
--
-- Table structure for table `posts_tags`
--
CREATE TABLE `posts_tags` (
`post_id` int(10) unsigned NOT NULL default '0',
`tag_id` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`post_id`,`tag_id`)
) TYPE=MyISAM;
-- --------------------------------------------------------
--
-- Table structure for table `tags`
--
CREATE TABLE `tags` (
`id` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(100) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
Давайте объявим ассоциацию в модели Post с нашими настройками таблиц:
/app/models/post.php hasAndBelongsToMany<?php
class Post extends AppModel{ var
$name = 'Post'; var
$hasAndBelongsToMany = array('Tag' => array(
'className' => 'Tag',
'joinTable' => 'posts_tags',
'foreignKey' => 'post_id',
'associationForeignKey'=> 'tag_id',
'conditions' => '',
'order' => '',
'limit' => '',
'unique' => true,
'finderQuery' => '',
'deleteQuery' => '', )
);
}
?>
Массив $hasAndBelongsToMany это что Cake использует для создания ассоциации между моделями Post и Tag. Каждый ключ таблицы позволяет вам настроить ассоциацию:
Теперь выполняя find() или findAll() запросы, используя модель Post, мы должны увидеть также ассоциированную модель Tag:
<?$post
= $this->Post->read(null, '2');print_r($post);?>
Если ни одна из ассоциированных моделей в системе еще не существует (например, вы хотите сохранить новый пост и соответствующий комментарий одновременно), вам нужно сначала сохранить главную, родительскую модель. Чтобы понять как это работает, давайте представим, что у нас есть действие в нашем Post Controller которое управляет сохранением новых постов и соответствующих комментариев. Пример ниже подразумевает, что вы воздали один пост и один комментарий.
/app/controllers/posts_controller.php (частично)function add()
{
if (!empty($this->data))
{
//Мы можем сохранить данные поста:
//они должны быть в $this->data['Post']
$this->Post->save($this->data);
//Теперь нам нужно сохранить данные комментария
//Но сначала нам нужно узнать ID
//поста, который мы только что сохранили...
$post_id = $this->Post->getLastInsertId();
//Теперь мы добавляем эту информацию в сохраняемые данные
//и сохраняем комментарий.
$this->data['Comment']['post_id'] = $post_id;
//Поскольку у нас Post hasMany Comments, мы можем получить доступ
//к модели комментария через модель Post:
$this->Post->Comment->save($this->data);
}
}
Если, все же, родительская модель уже существует в системе (например, добавление комментария к существующему посту), нам нужно знать ID родительской модели перед сохранением. Мы можем поместить этот ID в ссылку или как скрытый элемент в форме...
/app/controllers/posts_controller.php (partial)//Вот как будет выглядеть ссылка, если мы используем ее для передачи параметра...
function addComment($post_id)
{
if (!empty($this->data))
{
//Вы можете захотеть сделать данные $post_id более защищенными,
//но этого будет достаточно для работающего примера..
$this->data['Comment']['post_id'] = $post_id;
//Поскольку у нашего Post hasMany Comments, мы можем получить доступ
//доступ к модели Comment через модель Post:
$this->Post->Comment->save($this->data);
}
}
Если ID был пропущен как скрытый элемент формы, вы можете захотеть назвать поле (если используете HTML хелпер) это находится в конце данных, где и должно быть:
If the ID for the post is at $post['Post']['id']...
<?php echo $html->hidden('Comment/post_id', array('value' => $post['Post']['id'])); ?>
Таким образом, доступ к ID родительской модели Post можно получить от $this->data['Comment']['post_id'] и все готово к простому запросу $this->Post->Comment->save($this->data).
Этот самый способ будет работать если вы сохраняете несколько дочерних моделей, просто поместите их запрос save() в цикл (и не забудьте очистить информацию модели, используя Model::create()).
Подбивая итоги, если вы сохраняете ассоциированные данные (для belongTo, hasOne и hasMany типов ассоциаций), главное получение ID родительской модели и сохранение его в дочерней модели.
Сохранение hasAndBelongsToMany типа ассоциаций
Сохранение моделей, которые ассоциированы типами hasOne, belongTo и hasMany довольно просто: вы просто заполняете поле стороннего ключа ассоциированной модели. Когда это сделано вы просто делаете запрос save() на модели, и все связано корректно.
С hasAndBelongsToMany это чуток сложнее, но мы нашли способ упросить это максимально. Продолжая тему с нашим примером, нам понадобится особый тип формы, которая ассоциирует теги с постами. Давайте сейчас создадим форму, которая создает посты, и ассоциирует их с существующим списком тегов.
Вам может быть хочется создать форму, которая создает новые теги и ассоциирует их налету – но для простоты, мы пока просто покажем вам как ассоциировать их и позволить вам добираться до них.
Когда вы сохраняете модель саму по себе в Cake, имя тега (если вы используете HTML Хелпер) выглядит как 'Модель/имя_поля'. Давайте просто начнем с создания формы, которая создаст наш пост:
/app/views/posts/add.thtml
Форма для создания постов<h1>Write a New Post</h1>
<table>
<tr>
<td>Title:</td>
<td><?php echo $html->input('Post/title')?></td>
</tr>
<tr>
<td>Body:<td>
<td><?php echo $html->textarea('Post/body')?></td>
</tr>
<tr>
<td colspan="2">
<?php echo $html->hidden('Post/user_id', array('value'=>$this->controller->Session->read('User.id')))?>
<?php echo $html->hidden('Post/status' , array('value'=>'0'))?> <?php echo $html->submit('Save Post')?> </td> </tr>
</table>
/app/views/posts/add.thtml (Дополнительный код для ассоциирования с тегами)<h1>Write a New Post</h1>
<table>
<tr>
<td>Title:</td>
<td><?php echo $html->input('Post/title')?></td>
</tr>
<tr>
<td>Body:</td>
<td><?php echo $html->textarea('Post/body')?></td>
</tr>
<tr>
<td>Related Tags:</td>
<td><?php echo $html->selectTag('Tag/Tag', $tags, null, array('multiple' => 'multiple')) ?>
</td> </tr>
<tr>
<td colspan="2">
<?php echo $html->hidden('Post/user_id', array('value'=>$this->controller->Session->read('User.id')))?>
<?php echo $html->hidden('Post/status' , array('value'=>'0'))?>
<?php echo $html->submit('Save Post')?>
</td>
</tr>
</table>
Для запроса $this->Post->save() в контроллере, чтобы сохранить связи между этим новым постом и ассоциацией с тегами, имя поля должно быть в форме "Tag / Tag" (отображаемое имя атрибута будет выглядеть как 'data[ИмяМодели][ИмяМодели][]'). Подтвержденные данные должны быть одним ID или массивом ID-номеров связанных записей. Поскольку мы используем возможность выбора не одного тега, то подтвержденные данные для Tag / Tag будут массивом ID-номеров.
Переменная $tags здесь – просто массив где ключи это ID-номера возможных тегов, а значения это отображаемые имена тегов в многоэлементном выборе.
Смена ассоциаций на лету, используя bindModel() и unbindModel()
Вы можете случайно захотеть изменить информацию об ассоциациях моделей в необычных ситуациях, пока создаете свое приложение. Если настройка ассоциаций в файле модели дает слишком много (или недостаточно) информации, вы можете использовать две функции моделей чтобы связать и развязать ассоциации моделей.
Давайте сделаем несколько моделей так что мы сможем посмотреть как bindModel() и unbindModel() работают. Мы начнем с двух моделей:
leader.php и follower.php<?php
class Leader extends AppModel{ var
$name = 'Leader'; var
$hasMany = array(
'Follower' => array(
'className' => 'Follower',
'order' => 'Follower.rank'
) );
}
?><?php
class Follower extends AppModel
{
var $name = 'Follower';
}
?>
Теперь, в Leader Controller, мы можем использовать find() в модели Leader. Как вы можете увидеть выше, ассоциативный массив в модели Leader объявляет ассоциацию Leader hasMany Followers. Для демонстрации замысла давайте используем unbindModel() чтобы убрать эту ассоциацию.
leaders_controller.php (частично)function someAction()
{
//Это делает выборку Leaders и ассоциированные с ними Followers
$this->Leader->findAll();
//Давайте уберем hasMany...
$this->Leader->unbindModel(array('hasMany' => array('Follower')));
//Теперь используя функцию поиска вернем Leaders, но уже без Followers
$this->Leader->findAll();
//ЗАМЕЧАНИЕ: unbindModel распространится только на следующую функцию поиска..
//Дополнительный запрос поиска будет использовать настроенную ассоциированную информацию.
//Мы уже использовали функцию findAll() после unbindModel(), так что это сделает выборку
//Leaders с ассоциированными Followers еще раз...
$this->Leader->findAll();
}
Функция unbindModel() работает также с остальными ассоциациями: просто измените названия типа ассоциаций и имя класса модели. Основное применение unbindModel():
Общий unbindModel() пример
$this->Model->unbindModel(array('associationType' => array('associatedModelClassName')));
Теперь мы успешно убрали ассоциацию на лету, давайте добавим. Наша модель Leader нуждается в какой-то ассоциации с Principles. Файл модели для модели Principles голый, за исключением одной переменной $name выражения. Давайте ассоциируем Principles с нашей Leader на лету (но только для следующего запроса функции поиска):
leaders_controller.php (частично)funciton anotherAction()
{
//Нету никакой Leader hasMany Principles в leader.php-файле модели, так что
//поиск здесь просто сделает выборку Leaders.
$this->Leader->findAll();
//Давайте используем bindModel(), чтобы добавить ассоциацию к Principles модели:
$this->Leader->bindModel(
array('hasMany' => array(
'Principle' => array(
'className' => 'Principle'
)
)
)
);
//Теперь когда мы сделали корректную ассоциацию, мы можем использовать простую функцию поиска
//чтобы сделать выборку Leaders с ассоциированными Principles:
$this->Leader->findAll();
}
Функция bindModel() может быть удобной при создании новых ассоциаций, но она также может быть полезна если вы хотите изменить сортировку или другие параметры в данной ассоциации на лету.
Вот теперь это есть у вас. Основное использование bindModel это герметизация обычного ассоциативного массива внутрь массива, чьи ключи названы после типа ассоциации, которую вы пытаетесь создать:
//Общий bindModel() пример<?
$this
->Model->bindModel( array(
'associationName' => array(
'associatedModelClassName' => array(
// обычные ассоциативные ключи здесь...
) )
)
);
?>
Пожалуйста заметьте что в ваших таблицах должны быть корректно прописаны ключи (или ассоциативные массивы соответственно настроенные) чтобы связывать модели на лету.