Автоматическое объединение таблиц без нарушения поведения по умолчанию в Zend Framework

Ситуация такова: у меня есть две модели: «Действие» и «Пользователь». Эти модели относятся к действиям таблиц и «пользователям», соответственно.

В моей таблице действий содержится столбец user_id . В этот момент мне нужен обзор всех действий и пользователей, которым они назначены. Когда я использую $action->fetchAll() , у меня есть только идентификатор пользователя, поэтому я хочу иметь возможность присоединяться к данным из пользовательской модели, желательно, не делая вызов findDependentRowset() .

Я думал о создании пользовательских fetchAll() , fetchRow() и find() в моей модели, но это нарушило бы поведение по умолчанию.

Каков наилучший способ решить эту проблему? Любая помощь будет принята с благодарностью.

Solutions Collecting From Web of "Автоматическое объединение таблиц без нарушения поведения по умолчанию в Zend Framework"

Я разработал и реализовал функцию 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