假设我有以下域名:
class Store {
String name
static hasMany = [ products: StoreProduct ]
}
class Product {
String name
static hasMany = [ stores: StoreProduct ]
}
class StoreProduct {
BigDecimal discount
static belongsTo = [ store: Store, product: Product ]
static mapping = {
id composite: ['store', 'product']
}
换句话说,Store
和Product
之间存在多对多关系,中间StoreProduct
域类跟踪每个商店的个别折扣。
Grails内置支持一对多关系,因此您可以使用正确的字段名称传递ID列表,控制器会自动将ID解析为实体列表。但是,在这种情况下,它是一个多对多的中间域类。
我在Store
编辑视图中尝试了以下代码,以允许用户选择产品列表:
<g:each in="${products}" var="product" status="i">
<label class="checkbox">
<input type="checkbox" name="products" value="${product.id}"/>
${product.name}
</label>
</g:each>
但Grails会根据我对name
属性使用的内容抛出各种错误。我还尝试了以下input
名称:
products
products.product
products.product.id
product[0].product
product[0].product.id
但它们都没有正常工作。
我的问题是,Grails中是否存在对此类关系的内置支持,特别是在视图方面?
答案 0 :(得分:1)
按如下方式更改您的域名结构:
class Store {
String name
Set<Product> getProducts() {
StoreProduct.findAllByStore(this)*.product
}
}
class Product {
String name
Set<Store> getStores() {
StoreProduct.findAllByProduct(this)*.store
}
}
import org.apache.commons.lang.builder.HashCodeBuilder
class StoreProduct implements Serializable {
BigDecimal discount
Store store
Product product
static mapping = {
id composite: ['store', 'product']
version false
}
boolean equals(other) {
if (!(other instanceof StoreProduct)) {
return false
}
other.store?.id == store?.id &&
other.product?.id == product?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (store) builder.append(store.id)
if (product) builder.append(product.id)
builder.toHashCode()
}
}
答案 1 :(得分:0)
来自上面的域类: -
其中一个域(Store
或Product
)必须通过belongsTo
来承担关系的责任。有关详细信息,请参阅API。
包含StoreProduct
主键的域类(composite
)应实现Serializable
。
如果可用,请提供一个堆栈跟踪进行调试。