ActiveWeb: установка / получение модели не работает при вызове в шаблоне
При работе с устаревшей базой данных бывают случаи, когда я не могу правильно настроить отношения, используя belongs_to
аннотаций. В этом случае я попытался определить атрибут, указывающий на другой Model
Класс с его методами доступа следующим образом:
@Table("INTERVENTION")
@IdName("ITV_ID")
public class Intervention extends Model {
private InterventionModel interventionModel;
public InterventionModel getInterventionModel() {
return interventionModel;
}
public void setInterventionModel(InterventionModel interventionModel) {
this.interventionModel = interventionModel;
}
}
Я загружаю и настраиваю InterventionModel
в классе обслуживания без проблем следующим образом (intervention
экземпляр существует):
private void loadInterventionModel(final Intervention intervention) {
final InterventionModel model = InterventionModel.findById(intervention.getLongId());
intervention.setInterventionModel(model);
}
Проблема в том, что это не работает, когда я пытаюсь оценить InterventionModel
атрибуты в шаблоне FreeMarker:
"item_code:": ${intervention.intervention_model.imo_internal_code}
Вот сброшенная ошибка:
FreeMarker template error:
An error has occurred when reading existing sub-variable "intervention_model"; see cause exception! The type of the containing value was: extended_hash+string (app.models.Intervention wrapped into f.e.b.StringModel)
Caused by: java.lang.IllegalArgumentException: Attribute: 'intervention_model' is not defined in model: 'class app.models.Intervention.
Что мне здесь не хватает и почему это не работает так, как ожидалось? Как правило, если я объявлю атрибут в модели с его аксессорами (getter и setter), он будет доступен в шаблоне с помощью:
mymodel.my_attribute
2 ответа
Я думаю, я нашел причину. Кажется, что когда вы объявляете переменную экземпляра в модели класса, и эта переменная не относится к доступным атрибутам модели (столбцы таблицы), вы должны использовать snake_case
вместо camelCase
написание, т.е. вместо объявления:
public class Intervention extends Model {
...
private InterventionModel interventionModel;
public InterventionModel getInterventionModel() {
return interventionModel;
}
public void setInterventionModel(InterventionModel interventionModel) {
this.interventionModel = interventionModel;
}
}
используйте версию snake_case:
private InterventionModel intervention_model;
public InterventionModel getIntervention_model() {
return intervention_model;
}
public void setIntervention_model(InterventionModel intervention_model) {
this.intervention_model = intervention_model;
}
Таким образом, вы сможете получить к нему доступ в шаблоне, как и другие переменные, доступные в модели:
"label": "${intervention.intervention_model.imo_product_label}"
Вначале я считал, что преобразование было сделано автоматически. Вы можете сохранить camlCase
verion, - в этом случае вы должны использовать его и в своем шаблоне:
"label": "${intervention.interventionModel.imo_product_label}"
Надеюсь это поможет.
Если ваш класс InterventionModel
указывает на устаревшую таблицу, вы можете сделать это:
@Table("INTERVENTION")
@IdName("ITV_ID")
public class Intervention extends Model {
private InterventionModel interventionModel;
public InterventionModel getInterventionModel() {
return interventionModel;
}
public void setInterventionModel(InterventionModel interventionModel) {
this.interventionModel = interventionModel;
}
Object getImoProductLabel(){
return interventionModel.imo_product_label();
}
}
затем в шаблоне:
"label": "${intervention.imoProductLabel}"
таким образом, вы создадите метод не только для шаблона, но и в других местах кода и абстрагируете свой унаследованный код.