ibaralf
ibaralf

Reputation: 12528

GORM: hasMany of the same domain class

Just wondering if someone can suggest how the domain class schema should be. I have a domain class called Category, but there can be sub-categories with the same domain (Category). For example, an appliance Toaster can be under category Kitchen, sub-category SmallAppliance.

class Category {
   static hasMany = [appliances: Appliance, categories: Category] 
   String name
}

class Appliance {
   static belongsTo = Category
   static hasMany = [categories: Category]
}

Upvotes: 2

Views: 324

Answers (1)

dmahapatro
dmahapatro

Reputation: 50285

A small tweak needed to the Appliance domain class. Guess it!! :)

We don't need the hasMany relationship in Appliance for categories. The relationship goes like this:

Category --> SubCategory (type of Category) --> Appliance

An appliance belongsTo the parent category as well as to the subCategory which in turn is a Category itself. So belongsTo relationship is enough in appliance.

Use Instead:

class Appliance {
   static belongsTo = Category
   String name
}

class Category {
    String name
    static hasMany = [appliances: Appliance, subCategories: Category]
}

Here is a test case which can make understand things better:

//Category
def kitchen = new Category(name: "Kitchen")
kitchen.save()

//Appliance
def toaster = new Appliance(name: "Toaster")
kitchen.addToAppliances(toaster)
kitchen.save()

//Sub Categories
def electrical = new Category(name:  "Electrical")
//Electrical category is a sub category of Kitchen
kitchen.addToSubCategories(electrical)

//Toaster is an appliance of Category Kitchen and Sub Category Electrical
electrical.addToAppliances(toaster)
kitchen.save()

assert kitchen
assert toaster
assert electrical

assert kitchen.appliances.size() == 1
kitchen.appliances.each{assert it.name == 'Toaster'}

assert kitchen.subCategories.size() == 1
kitchen.subCategories.each {assert it.name == 'Electrical'}

assert electrical.appliances.size() == 1
electrical.appliances.each {assert it.name == 'Toaster'}

Let know if it is still unclear.

Upvotes: 3

Related Questions