Ситуация такова: у меня есть две модели: «Действие» и «Пользователь». Эти модели относятся к действиям таблиц и «пользователям», соответственно.
В моей таблице действий содержится столбец user_id
. В этот момент мне нужен обзор всех действий и пользователей, которым они назначены. Когда я использую $action->fetchAll()
, у меня есть только идентификатор пользователя, поэтому я хочу иметь возможность присоединяться к данным из пользовательской модели, желательно, не делая вызов findDependentRowset()
.
Я думал о создании пользовательских fetchAll()
, fetchRow()
и find()
в моей модели, но это нарушило бы поведение по умолчанию.
Каков наилучший способ решить эту проблему? Любая помощь будет принята с благодарностью.
Я разработал и реализовал функцию table-relations в Zend Framework.
Мой первый комментарий состоит в том, что вы бы не использовали findDependentRowset()
любом случае – вы бы использовали findParentRow()
если Action имеет ссылку на внешний ключ для пользователя.
$actionTable = new Action(); $actionRowset = $actionTable->fetchAll(); foreach ($actionRowset as $actionRow) { $userRow = $actionRow->findParentRow('User'); }
Изменить: в цикле теперь у вас есть объект $ actionRow и $ userRow. Вы можете записывать изменения в базу данных через любой объект, изменяя поля объекта и вызывая save()
объекта.
Вы также можете использовать класс Zend_Db_Table_Select (который был реализован после того, как я покинул проект), чтобы получить Rowset на основе соединения между Action и User.
$actionTable = new Action(); $actionQuery = $actionTable->select() ->setIntegrityCheck(false) // allows joins ->from($actionTable) ->join('user', 'user.id = action.user_id'); $joinedRowset = $actionTable->fetchAll($actionQuery); foreach ($joinedRowset as $joinedRow) { print_r($joinedRow->toArray()); }
Обратите внимание, что такой Rowset, основанный на запросе соединения, доступен только для чтения. Вы не можете устанавливать значения полей в объектах Row и вызывать save()
чтобы отправлять изменения в базу данных.
Изменить: Невозможно создать произвольный объединенный результирующий набор, доступный для записи. Рассмотрим простой пример, основанный на объединенном результирующем наборе:
action_id action_type user_id user_name 1 Buy 1 Bill 2 Sell 1 Bill 3 Buy 2 Aron 4 Sell 2 Aron
Далее для строки с action_id = 1, я меняю одно из полей, которые пришли из объекта User:
$joinedRow->user_name = 'William'; $joinedRow->save();
Вопросы: когда я просматриваю следующую строку с action_id = 2, должен ли я видеть «Билл» или «Уильям»? Если «Уильям», означает ли это, что сохранение строки 1 должно автоматически обновлять «Билл» до «Уильяма» во всех остальных строках этого набора результатов? Или это означает, что save()
автоматически перезапускает SQL-запрос, чтобы получить обновленный набор результатов из базы данных? Что делать, если запрос занимает много времени?
Также рассмотрим объектно-ориентированный дизайн. Каждая строка представляет собой отдельный объект. Уместно ли, что вызов save()
на одном объекте имеет побочный эффект изменения значений в отдельном объекте (даже если они являются частью одного и того же набора объектов)? Это похоже на форму Content Coupling для меня.
Приведенный выше пример является относительно простым запросом, но также разрешены гораздо более сложные запросы. Zend_Db не может анализировать запросы с намерением рассказать записываемые результаты из результатов только для чтения. Именно поэтому представления MySQL не обновляются.
Вы всегда можете сделать представление в своей базе данных, которая сделает это для вас.
CREATE OR REPLACE VIEW VwAction AS SELECT [columns] FROM action LEFT JOIN user ON user.id = action.user_id
Тогда просто используйте
$vwAction->fetchAll();
Просто помните, что представления в MySQL доступны только для чтения (если предположить, что это MySQL)
не создает таблицу sql представления хорошее решение для совместного использования? и после простого класса таблицы для доступа к нему
Я бы подумал, что лучше, если ваша логика в sql, чем в php