Автоматически присоединяющиеся таблицы, не повреждая поведение по умолчанию в Платформе Зенда

1 - Эта проблема связана с тем, что any используется неправильно. Подробнее см. Руководство Mockito. Ниже мой пример не использует any и проблема исчезнет.

2 - Чтобы охватить 2 ветви if, я бы порекомендовал ниже контрольные примеры.

@Test
public void onApplicationEventShouldSetEnvironmentWhenApplicationEnvironmentPreparedEvent() {
    ConfigurableEnvironment actualEnvironment = null;

    // Given a listener with overridden setSystemVariables() to store passed env.
    LoggingListener loggingListener = new LoggingListener() {
        @Override
        void setSystemVariables(ConfigurableEnvironment var){
            actualEnvironment = var;
        }
    };

    // Given some dummy environment which is delivered by an event.
    ConfigurableEnvironment expectedEnvironment = new ConfigurableEnvironment();

    // Given a mocked event with above dummy environment.
    ApplicationEvent mockedEvent = Mockito(ApplicationEnvironmentPreparedEvent.class);
    Mockito.when(mockedEvent.getEnvironment()).returns(expectedEnvironment);

    // When call a method under test
    loggingListener.onApplicationEvent(mockedEvent);

    // Then make sure the given environment was passed and set correctly
    assertSame(expectedEnvironment, actualEnvironment);
}

@Test
public void onApplicationEventShouldSkipNotApplicationEnvironmentPreparedEvent() {
    // Given a listener with overridden setSystemVariables() to fail the test if called.
    LoggingListener loggingListener = new LoggingListener() {
        @Override
        void setSystemVariables(ConfigurableEnvironment var){
            fail("This method should not be called");
        }
    };

    // Given a mocked other (not ApplicationEnvironmentPreparedEvent) event.
    ApplicationEvent mockedEvent = Mockito(UnknownEvent.class);

    // When call a method under test
    loggingListener.onApplicationEvent(mockedEvent);

    // Then make sure an environment was not asked at all.
    Mockito.verify(mockedEvent.getEnvironment(), never);
}

Обратите внимание, это не компилируемый код, потому что я не знаю вашего полного производственного кода, поэтому воспринимайте это как идею применить его к реальному коду с соответствующими изменениями.

7
задан A J 25 January 2016 в 12:58
поделиться

3 ответа

Я разработал и реализовал опцию связей между таблицами в Платформе Зенда.

Мой первый комментарий - то, что Вы не использовали бы findDependentRowset() так или иначе - Вы использовали бы findParentRow() если Действие имеет ссылку внешнего ключа на Пользователя.

$actionTable = new Action();
$actionRowset = $actionTable->fetchAll();
foreach ($actionRowset as $actionRow) {
  $userRow = $actionRow->findParentRow('User');
}

Править: В цикле у Вас теперь есть $actionRow и объект $userRow. Можно записать изменения обратно в базе данных через любой объект путем изменения полей объекта и вызова save() на объекте.

Можно также использовать класс Zend_Db_Table_Select (который был реализован после того, как я оставил проект) получать Набор строк на основе соединения между Действием и Пользователем.

$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());
}

Обратите внимание, что такой Набор строк на основе запроса соединения только для чтения. Вы не можете установить значения полей в Объектах строки и вызове 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, я изменяю одно из полей, которые прибыли из Пользовательского объекта:

$joinedRow->user_name = 'William';
$joinedRow->save();

Вопросы: когда я просматриваю следующую строку с action_id=2, я должен видеть 'счет' или 'William'? Если 'William', это означает, что сохранение строки 1 должно автоматически обновить 'счет' 'William' во всех других строках в этом наборе результатов? Или это означает это save() автоматически повторно выполняет SQL-запрос для получения обновленного набора результатов от базы данных? Что, если запрос является трудоемким?

Также рассмотрите объектно-ориентированный дизайн. Каждая строка является отдельным объектом. Действительно ли это является соответствующим тот вызов save() на одном объекте имеет побочный эффект изменения значений в отдельном объекте (даже если они - часть того же набора объектов)? Это походит на форму Содержания, Связывающегося со мной.

Примером выше является относительно простой запрос, но намного более сложные запросы также разрешены. Zend_Db не может проанализировать запросы с намерением сказать перезаписываемые результаты результатов только для чтения. Это также, почему представления MySQL не обновляемы.

14
ответ дан 6 December 2019 в 11:53
поделиться

Вы могли всегда делать представление в своей базе данных, которая делает соединение для Вас.

CREATE OR REPLACE VIEW VwAction AS
SELECT [columns]
  FROM action
  LEFT JOIN user
    ON user.id = action.user_id

Затем просто используйте

$vwAction->fetchAll();

Просто помните, что представления в MySQL только для чтения (предполагающий, что это - MySQL),

2
ответ дан 6 December 2019 в 11:53
поделиться

Разве создание таблицы sql представления не является хорошим решением для объединения? и после простого класса таблицы для доступа к нему

я бы подумал, что лучше, если ваша логика будет в sql, чем в php

1
ответ дан 6 December 2019 в 11:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: