How-to: Связывание свойств
Пример 1
Условие
Определены понятия Страна, Регион и Город. Регион и город всегда находятся к некоторой стране. Для города может быть выбран регион, но может быть и не задан.
CLASS Country 'Страна';
name 'Имя' = DATA ISTRING[100] (Country) IN id;
CLASS Region 'Регион';
name 'Имя' = DATA ISTRING[100] (Region) IN id;
country 'Страна' = DATA Country (Region) NONULL DELETE;
nameCountry 'Страна' (Region r)= name(country(r)) IN id;
CLASS City 'Город';
name 'Имя' = DATA ISTRING[100] (City);
country 'Страна' = DATA Country (City) NONULL DELETE;
nameCountry (City c) = name(country(c));
region 'Регион' = DATA Region (City);
nameRegion (City c) = name(region(c));
FORM cities 'Города'
OBJECTS c = City
PROPERTIES(c) name, nameCountry, nameRegion, NEW, DELETE
;
NAVIGATOR {
NEW cities;
}
Нужно определить логику, что город может быть привязан только к региону той же страны, в которой он находится.
Решение
CONSTRAINT country(City c) != country(region(c)) CHECKED BY region[City] MESSAGE 'Страна региона города должна совпадать со страной города';
При помощи инструкции CONSTRAINT
указывается условие, которое должно принимать всегда значение NULL
. В данном случае ограничение на основе этого условия будет срабатывать в том случае, если заданы страна для города, регион для города, страна для региона, и страна региона не совпадет со страной города. Конструкция CHECKED BY
указывает, что при выборе региона в диалоге будут, по умолчанию, фильтроваться регионы таким образом, чтобы не нарушить это ограничение. Следует отметить, что если страна для города при вводе еще не задана, то условие будет при любом условии NULL
, и в диалоге будут показаны все существующие регионы.
Пример 2
Условие
Аналогично Примеру 1.
Нужно сделать, чтобы при выборе региона автоматически проставлялась страна.
Решение
WHEN LOCAL CHANGED(region(City c)) AND NOT CHANGED(country(c)) DO {
country(c) <- country(region(c));
}
Следует отметить, что после того, как пользователь выберет регион и будет проставлена страна, то при повторном вызове диалога будут фильтроваться уже регионы выбранный страны. Если пользователь захочет опять увидеть все регионы, то ему нужно будет сначала сбросить страну. Выражение обозначающее, что страна не изменилась, добавляется для того, что если города будут изменяться внешними действиями, которые изменяют одновременно и страну и регион, то не происходило замещение страны этим событием.
Пример 3
Условие
Аналогично Примеру 1.
Нужно сделать такую же связь региона и города, но чтобы регион нельзя было выбрать, не задав сначала страну.
Решение
CONSTRAINT region(City c) AND NOT country(c) = country(region(c)) CHECKED BY region[City] MESSAGE 'Страна региона города должна совпадать со страной города';
Разница с первым примером заключается в том, что в новом условии, если выбран регион, то оно будет истинным, если не задана страна. Таким образом и в диалоге в этом случае не будет отображаться ни один регион.
Пример 4
Условие
Аналогично Примеру 1.
Если пользователь сначала выберет регион, а потом страну, которая не соответствует изначальному региону, то при попытки сохранения пользователь получит ошибку.
Нужно сдела ть, чтобы при изменении страны, если регион не соответствует стране, то он сбрасывался.
Решение
WHEN LOCAL CHANGED(country(City c)) AND country(c) != country(region(c)) DO {
region(c) <- NULL;
}