Я пытаюсь получить правильное использование объектов Command. И у меня есть некоторые вопросы.Grails: объекты команд, шаблоны просмотра и поля условной формы?
Учитывая общий домен, например:
package com.foo
class Ticket {
Customer customer
Product product
Defect defect
Solution solution
String comment
static constraints = {
customer nullable:false
product nullable:false
defect nullable:true
solution nullable:true
comment nullable:true
}
}
Затем, рассмотрит следующие правил с формы в билете:
- Клиент может быть выбран только на создание. При редактировании на дисплее не должно отображаться , вместо этого отображается метка;
- Продукт можно выбрать только при создании. Тем не менее, при редактировании, выбор должен быть отключен;
- Дефект можно выбрать либо при создании, либо при редактировании;
- Решение не может быть установленным в этой форме вообще.
- Комментарий может быть сообщен только пользователям с определенной ролью (например, SpringSecurity). Если у пользователя нет такой роли, текстовая область должна быть отключена.
Теперь, что я хочу знать:
Что бы быть лучшим подходом к использованию CommandObject для обработки этот сценарий?
- 1 единственный объект CommandObject для обоих действий?
- 1 CommandObject для каждого действия?
- В случае одного CommandObject, как запретить пользователям взламывать программу, например, передавать запрещенный параметр?
Что было бы лучшим подходом к реализации правил формы? То есть, какое поле отображается/включено/отключено в каждом случае.
- Есть ли какой-либо образец или рекомендация для этого случая?
- Должны ли такие правила быть записаны в реальной форме?
- Или должна ли форма «спросить» кого-нибудь? Возможно, CommandObject? Или сам экземпляр домена?
Например, рассмотрим суть этой форме в:
<div class="fieldcontain ${hasErrors(bean:ticketInstance, field:'customer', 'error')} required">
<label for="customer">
<g:message code="ticket.customer.label" default="Customer" />
<span class="required-indicator">*</span>
</label>
<g:if test="${ticketInstance.id}">
<span class="label read-only">${ticketInstance.customer.name}</span>
</g:if>
<g:else>
<g:select id="customer" name="customer.id" from="${Customer.list()}" optionKey="id"
required="" disabled="" value="${ticketInstance?.customer?.id}" class="many-to-one"/>
</g:else>
</div>
В этом случае нет много проблем, потому что проверка довольно проста. То есть:
<g:if test="${ticketInstance.id}">
...
Однако рассмотрите более сложное правило. Что-то вроде:
<g:if test="${ticketInstance.id && currentUser.granted('SOME_RULE') && ticketInstance.someField != null}">
...
И так далее.
Теперь, есть несколько проблем с этим подходом:
- Это довольно многословен, и, следовательно, склонны к ошибкам.
- Предположим, что такое правило было распространено среди других полей. В этом случае мне придется каким-то образом управлять им (локальная переменная, дублировать код и т. Д.).
- И плюс, для этого мне понадобится свойство Id в моем TicketCommand, которое я не знаю, если это хорошая идея.
И, таким образом, мне было интересно, есть ли какой-либо образец или рекомендация, которая может быть использована для улучшения этих сценариев. То есть, что-то, что инкапсулирует такую сложность. Например:
<g:if test="${cmd.customerAllowed}">
...
Где CommandObject может быть что-то вдоль линий:
@Validateable
class TicketCreateCommand {
def currentUser //injected somehow..
Customer customer
Product product
Defect defect
String comment
static constraints = {
importFrom Ticket
}
boolean isNew() {
true
}
boolean isCustomerAllowed() {
this.new && currentUser.granted('SOME_RULE') && this.someField != null
//some more rules if necessary..
}
boolean isSomeFieldAllowed() {
//rules for creating
}
}
И CommandObject для редактирования:
@Validateable
class TicketEditCommand {
def currentUser //injected somehow..
Customer customer
Product product
Defect defect
String comment
static constraints = {
importFrom Ticket
}
boolean isNew() {
false
}
boolean isCustomerAllowed() {
this.new && currentUser.granted('SOME_RULE') && this.someField != null
//some more rules if necessary..
}
boolean isSomeFieldAllowed() {
//rules for editing
}
}
Может CommndObject держать такую ответственность? Если нет, есть ли другой лучший способ централизовать такие сложности? Кроме того, как я уже говорил, клиент недвижимости не может быть установлен на обновление. Как с этим бороться?
Ну, я считаю, что это в значительной степени.
Буду признателен за любые мнения и предложения. Любая ссылка на какой-то учебник была бы блестящей.
PS: Для тех, кто хочет посмотреть, полный проект доступен на github.
Спасибо за ваш ответ. 2 Командные объекты: ОК. Теперь я уточнил свой вопрос для уточнения. В принципе, я хотел бы знать, есть ли способ/шаблон для централизации сложностей правил каждого поля формы, чтобы код формы не становился настолько загрязненным и сложным. Кроме того, в случае с двумя объектами Command, как предотвратить (на стороне сервера) из определенных полей заполняется пользователем. Я имею в виду, в моем примере: 'TicketEditCommand' пользователь мог« взломать »HTML и вставить' ', и он будет работать, это? –
Я имел в виду: «код формы ** не становится настолько загрязненным и сложным». –
Я отредактировал свой ответ для решения этих вопросов. –