2015-08-17 5 views
0

Я создал новый проект Grails 2.5.1 с двумя доменами и использовал генерировать все для создания лесов. Один из доменов hasMany другого домена: Пользователь hasMany ролей. Когда я запускаю приложение и создаю нового пользователя и выбираю роль для пользователя, он добавляет его. Я могу добавить несколько ролей для пользователя или удалить их, за исключением последнего. Я не могу удалить последнюю. Если я попытаюсь удалить все роли для пользователя, он игнорирует его и оставляет роли, которые были выбраны ранее. (Я нашел такое же поведение в Grails 2.4.4.)Grails 2.5 scaffolding не удаляет последний hasMany во время связывания

Домены:

class Role { 
    String name 
} 

class User { 
    String name 
    static hasMany = [roles: Role] 
} 

Вид строительных лесов создает HTML выберите поле с:

<g:select name="roles" from="${myapp.Role.list()}" 
    multiple="multiple" optionKey="id" size="5" 
    value="${userInstance?.roles*.id}" class="many-to-many"/> 

Создание этого HTML:

<select id="roles" class="many-to-many" size="5" multiple="multiple" name="roles"> 
<option selected="selected" value="1">myapp.Role : 1</option> 
<option value="2">myapp.Role : 2</option> 
</select> 

Воспроизводить:

  1. Запустите приложение
  2. Создать несколько ролей
  3. Создания нового пользователя, введите имя, выберите одну или несколько ролей, и нажмите кнопку Создать
  4. редактирования пользователя, отмените роли, и нажмите кнопку Обновить
  5. Обратите внимание, что предыдущие роли по-прежнему выбран

Я понимаю, что ничего не связано с формой для этого поля, если ничего не выбрано. Я могу исправить это, выполнив user.roles.clear() перед привязкой. Это работает, но мне интересно ...

Действительно ли строительные леса не предназначены для обработки этого случая? Или я делаю что-то неправильно, например, как мои домены закодированы? Есть ли лучшее решение, чем редактирование лесов, чтобы очистить роли до привязки?

+0

попробуйте добавить 'ownTo = [user: User]' в модель доменной модели. В документации есть строка ** _ Каскадное поведение по умолчанию - это каскадное сохранение и обновление, но не удаление, если также не указано имя пользователя _ **; Я не уверен, что это сработает, но стоит попробовать. Если это не сработает, я бы предложил вызвать 'user.roles.clear()' перед связыванием так же, как вы предлагали. – ionutab

+0

@ionutab: Я хочу отношения «многие ко многим». Несколько пользователей могут иметь одну и ту же роль. И, конечно, пользователь может иметь много ролей. Таким образом, я не могу использовать belongsTo. – tbird

+0

Если вы хотите, чтобы отношение «многие ко многим», чем приведенный выше код, неверно. Вы также должны иметь hasMany = [] adnotation в модели домена ролей. Кроме того, в классе Role вам необходимо указать владельца отношения, Пользователь, в вашем случае, используя карту, принадлежащую к карте. [читайте здесь] (https://grails.github.io/grails-doc/latest/guide/GORM.html#manyToMany) – ionutab

ответ

0

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

Вам нужно будет изменить вид лесов, чтобы достичь желаемого. Использовать noSelection свойство g: выберите, чтобы указать, что должно быть значением по умолчанию, если пользователь не хочет выбирать какую-либо существующую роль.

Ваш г: выберите тег, то будет:

<g:select name="roles" from="${myapp.Role.list()}" 
    noSelection="['': '--NoSelection--']" 
    multiple="multiple" optionKey="id" size="5" 
    value="${userInstance?.roles*.id}" class="many-to-many"/> 

и подмостей позволяет создавать некоторые основные интерфейсы CRUD для класса домена. Он не поддерживает много вещей, которые вы должны реализовать самостоятельно.

+0

Вы правы: «[Функция лесов в настоящее время не поддерживает многие-ко-многим] (http://grails.github.io/grails-doc/2.5.1/guide/GORM.html#manyToMany)». Исправление 'noSelection' работает, если пользователь действительно его выбирает. Если они отменяют выбор всех параметров, это та же проблема. И, если вы многократно выбираете «нет выбора» и роль, он дает ошибку «Не удалось найти соответствующий конструктор». Javascript может исправить все это, но становится беспорядочным. Решение 'clear()' кажется лучше, поскольку оно работает без выбора и не дает ошибки в любом случае. – tbird